Нужно преобразовать List<String[]> в Dictionary<string, string[]>

Я пытаюсь преобразовать 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()

Когда вы используете .Take(...), возвращается IEnumerable, но ваш контракт представляет собой массив. Попробуйте удалить .All() вместо этого добавить .ToArray()

itsdaniel0 21.02.2023 20:31

Выбросьте все это, купите себе приличную CSV-библиотеку, десериализуйте ее в приличную модель и спите как младенец.

Fildor 21.02.2023 20:38

Какое сообщение об ошибке вы получаете? Обычно в сообщении об ошибке сообщается, какая у вас проблема.

Fabio 21.02.2023 20:39

Не могли бы вы предоставить пример входных данных и ожидаемый результат?

Peter Csala 21.02.2023 20:40
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
Уроки CSS 6
Уроки CSS 6
Здравствуйте дорогие читатели, я Ферди Сефа Дюзгюн, сегодня мы продолжим с вами уроки css. Сегодня мы снова продолжим с так называемых классов.
Что такое Css? Для чего он используется?
Что такое Css? Для чего он используется?
CSS, или "Каскадные таблицы стилей", - это язык стилей, используемый в веб-страницах. CSS является одним из основных инструментов веб-разработки...
0
4
63
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Как я вижу, у вас есть 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 21.02.2023 21:06

@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}}? Что-то другое?

Dmitry Bychenko 21.02.2023 21:11

Извините, что не выразился более ясно. Я хотел бы, чтобы каждый уникальный ключ имел массив всех значений для указанного ключа. На мой взгляд, это будет List<String[]> для ключей, которые сталкиваются.

bitcoinluvr6969 21.02.2023 21:12

@bitcoinluvr6969: поэтому мы можем сгруппировать все неуникальные ключи с помощью GroupBy, а затем объединить все значения с помощью SelectMany

Dmitry Bychenko 21.02.2023 21:18

Замените 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), ваш оригинальный подход должен дать ожидаемый результат.

Другие вопросы по теме