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

117

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

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

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

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

Jonnster
источник
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")) ...
dasblinkenlight
источник
это не удастся, если список выглядит как строка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который позволяет использовать несколько значений для каждого ключа.

Lukazoid
источник
0

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

var dictionary = myList.ToDictionary(x => x);
dtsg
источник
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
      }
    }
Праная Рана
источник