Я пытаюсь преобразовать List<String[]> в Dictionary<string, string[]>, но то, что я пытаюсь сделать, либо выдает ошибки, либо вылетает. Что такое верное решение?
List<String[]> logs = new List<String[]>();
foreach (string datum in data.Split('\n'))
{
string[] cols = datum.Split(",");
logs.Append(cols);
}
Dictionary<string, string[]> dict = logs.ToDictionary(l => l[0], l => l.Skip(1).Take(4).All());
foreach (KeyValuePair<string, string[]> kvp in dict)
{
Debug.WriteLine("k = {0}, Value = {1}", kvp.Key, kvp.Value);
}
InitializeComponent();
Debug.WriteLine("end");
То, что я пробовал выше, в частности, проблема в строке:
Dictionary<string, string[]> dict = logs.ToDictionary(l => l[0], l => l.Skip(1).Take(4).All());
Я также пробовал без .All()
Выбросьте все это, купите себе приличную CSV-библиотеку, десериализуйте ее в приличную модель и спите как младенец.
Какое сообщение об ошибке вы получаете? Обычно в сообщении об ошибке сообщается, какая у вас проблема.
Не могли бы вы предоставить пример входных данных и ожидаемый результат?
Как я вижу, у вас есть string data, который вы хотите превратить в словарь; если вы можете гарантировать, что ключи уникальны:
Dictionary<string, string[]> dict = data
.Split('\n', StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Split(',', 6))
.ToDictionary(items => items[0],
items => items.Skip(1).Take(4).ToArray());
Обновлено: если возможны повторяющиеся ключи, и вы хотите сгруппировать значения для этих ключей, вы можете использовать GroupBy, а затем объединить и сгладить значения с помощью SelectMany:
Dictionary<string, string[]> dict = data
.Split('\n', StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Split(','))
.GroupBy(items => items[0], // 1st item is the key
items => items.Skip(1)) // all the rest will be value
.ToDictionary(group => group.Key,
group => group.SelectMany(item => item).ToArray());
Это кажется самым простым, но у меня есть другая проблема. У меня есть повторяющиеся ключи, однако я хотел бы сохранить эти значения. Как я могу это сделать?
@bitcoinluvr6969: не могли бы вы привести пример, каким образом вы хотите сохранить значения. Если у вас есть такие строки, как A,1,2,3,4 и A,5,6,7,8, что должно быть в словаре? {A, {1, 2, 3. 4}}? {A, {5, 6, 7, 8}}? {A, {1,2,3,4,5,6,7,8}}? Что-то другое?
Извините, что не выразился более ясно. Я хотел бы, чтобы каждый уникальный ключ имел массив всех значений для указанного ключа. На мой взгляд, это будет List<String[]> для ключей, которые сталкиваются.
@bitcoinluvr6969: поэтому мы можем сгруппировать все неуникальные ключи с помощью GroupBy, а затем объединить все значения с помощью SelectMany
Замените All() на ToArray(), чтобы преобразовать IEnumerable, возвращаемый Take(4), в string[]. Вот обновленная версия кода, которая должна работать:
List<String[]> logs = new List<String[]>();
foreach (string datum in data.Split('\n'))
{
string[] cols = datum.Split(",");
logs. Append(cols);
}
Dictionary<string, string[]> dict = logs.ToDictionary(l => l[0], l => l.Skip(1).Take(4).ToArray());
foreach (KeyValuePair<string, string[]> kvp in dict)
{
Debug.WriteLine("k = {0}, Value = {1}", kvp.Key, string.Join(",", kvp.Value));
}
Это должно создать словарь с первым элементом каждого String[] в logs в качестве ключа, а следующие 4 элемента — в качестве значения в string[]. Обновленный вызов Debug.WriteLine выведет значение словаря в виде строки, разделенной запятыми, чтобы ее было легче читать.
Проблема в вашем коде в том, что вы используете метод .Append() для добавления значений в список logs?
Из документов: Enumerable.Append
Этот метод не изменяет элементы коллекции. Вместо, он создает копию коллекции с новым элементом.
Поэтому, если вы замените logs.Append(cols) на logs.Add(cols), ваш оригинальный подход должен дать ожидаемый результат.
Когда вы используете .Take(...), возвращается IEnumerable, но ваш контракт представляет собой массив. Попробуйте удалить .All() вместо этого добавить .ToArray()