C # Преобразование списка <строка> в словарь <строка, строка>


117

Это может показаться странным, но, игнорируя это, существует ли хороший краткий способ преобразования списка в словарь, где каждая пара значений ключа в словаре - это просто каждая строка в списке. т.е.

List = string1, string2, string3
Dictionary = string1/string1, string2/string2, string3/string3

Я провел много поисков, и только на Stackoverflow есть буквально десятки примеров, когда это делается в противоположном направлении, но не в этом направлении.

Причина в том, что у меня есть два третьих компонента, и изменить их не в моих руках. Один возвращает список адресов электронной почты в виде списка, а другой отправляет электронные письма, в которых параметр To является словарем. Ключом словаря является адрес электронной почты, а значением - их настоящее имя. Однако я не знаю настоящего имени, но он по-прежнему работает, если вы также установите настоящее имя в адрес электронной почты. Поэтому почему я хочу преобразовать список в словарь. Есть много способов сделать это. Цикл foreach в списке, который добавляет kvp в словарь. Но мне нравится лаконичный код, и мне было интересно, есть ли однострочное решение.


1
У меня есть лучшее решение по вашей уважительной причине, честно.

2
Вы можете захотеть увидеть, соответствует ли HashSet <> вашим требованиям, вместо использования Dictionary <,>.
Greg

Более прямо, чем вышеперечисленные комментаторы: если вы объясните причину своего желания, кто-то, вероятно, предложит лучшее решение.
Тим С.

1
Нет лучшего решения. У меня есть сторонний компонент, который возвращает список строк, это адреса электронной почты. У меня есть еще один сторонний компонент, который отправляет электронные письма, в которых он передает Dictionary <string, string>, где ключ - это адрес электронной почты, а значение - настоящее имя получателя. Однако настоящее имя также может быть просто адресом электронной почты, поэтому я хочу преобразовать List <string> в Dictionary <string, string>
Jonnster

Ответы:


244

Попробуй это:

var res = list.ToDictionary(x => x, x => x);

Первая лямбда позволяет вам выбрать ключ, вторая - значение.

Вы можете поиграть с ним и сделать значения отличными от ключей, например:

var res = list.ToDictionary(x => x, x => string.Format("Val: {0}", x));

Если в вашем списке есть дубликаты, добавьте Distinct()следующее:

var res = list.Distinct().ToDictionary(x => x, x => x);

ИЗМЕНИТЬ Чтобы прокомментировать действительную причину, я думаю, что единственная причина, которая может быть действительной для подобных преобразований, заключается в том, что в какой-то момент ключи и значения в результирующем словаре будут расходиться. Например, вы должны выполнить первоначальное преобразование, а затем заменить некоторые значения на что-то другое. Если ключи и значения всегда будут одинаковыми, это HashSet<String>будет намного лучше для вашей ситуации:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...

это не удастся, если список выглядит как строка1, строка2, строка3, строка1
Пранай Рана

3
@PranayRana Да, было бы. Вы можете добавить .Distinct()после, listчтобы избежать этого.
dasblinkenlight

Спасибо. Я пропустил функцию ToDictionary. Спасибо всем, кто дал такой же ответ. Я проголосовал за всех, но могу принять только один ответ. Это был только один с добавленным кодом Distinct, поэтому, на мой взгляд, он был наиболее полным.
Jonnster

11

Использовать это:

var dict = list.ToDictionary(x => x);

См. MSDN для получения дополнительной информации.

Как указывает Пранай в комментариях, это не удастся, если элемент существует в списке несколько раз.
В зависимости от ваших конкретных требований вы можете либо использовать var dict = list.Distinct().ToDictionary(x => x);для получения словаря отдельных элементов, либо ToLookupвместо этого:

var dict = list.ToLookup(x => x);

Это вернет, ILookup<string, string>который по сути такой же, как IDictionary<string, IEnumerable<string>>, поэтому у вас будет список отдельных ключей с каждым экземпляром строки под ним.


это не удастся, если список выглядит как строка1, строка2, строка3, строка1
Пранай Рана

1

Используя ToDictionary:

var dictionary = list.ToDictionary(s => s);

Если возможно, что любая строка может повторяться, либо Distinctсначала выполните вызов в списке (для удаления дубликатов), либо используйте, ToLookupкоторый позволяет использовать несколько значений для каждого ключа.


0

Ты можешь использовать:

var dictionary = myList.ToDictionary(x => x);

0

РЕДАКТИРОВАТЬ

другой способ справиться с дублированием - это сделать так

var dic = slist.Select((element, index)=> new{element,index} )
            .ToDictionary(ele=>ele.index.ToString(), ele=>ele.element);

или


простой способ сделать это

var res = list.ToDictionary(str => str, str=> str); 

но убедитесь, что строка не повторяется ... опять же, иначе приведенный выше код не будет работать для вас

если есть повторяющаяся строка, то лучше сделать так

Dictionary<string,string> dic= new Dictionary<string,string> ();

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.