C # Перетворити список <string> у словник <рядок, рядок>


117

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

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

Я здійснив багато пошукових записів, і тільки в Stackoverflow є буквально десятки прикладів того, що це робиться в зворотному напрямку, але не в цьому напрямку.

Причиною цього є те, що у мене є дві складові частини третьої частини, і їх зміна не вдається. Один повертає список адрес електронної пошти у вигляді списку, а інший надсилає електронні листи, де параметром To є словник. Ключовим словником є ​​адреса електронної пошти, а значення - їх справжнє ім’я. Однак я не знаю справжнього імені, але воно все ще працює, якщо ви також встановите справжнє ім’я на адресу електронної пошти. Тому я хочу перетворити список у словник. Існує безліч способів зробити це. Цикл foreach у списку, який додає kvp до словника. Але мені подобається лаконічний код і цікавився, чи є рішення в одному рядку.


1
Я маю краще рішення з вашої поважної причини, чесно.

2
Ви можете дізнатися, чи відповідає HashSet <> вашим вимогам, а не використовувати словник <,>.
Грег

Більш безпосередньо, ніж вищезгадані коментатори: Якщо ви поясните свою причину цього, хтось, можливо, може запропонувати краще рішення.
Тім С.

1
Немає кращого рішення. У мене є сторонній компонент, який повертає список рядків, це адреси електронної пошти. У мене є ще один сторонній компонент, який надсилає електронні листи там, де він передає словник <рядок, рядок>, де ключем є адреса електронної пошти, а значення - справжнє ім'я одержувачів. Однак справжнє ім’я також може бути просто адресою електронної пошти знову, тому я хочу перетворити список <string> у словник <рядок, рядок>
Jonnster

Відповіді:


243

Спробуйте це:

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);

EDIT Щоб прокоментувати дійсну причину, я думаю, що єдиною причиною, яка могла б бути дійсною для таких перетворень, є те, що в якийсь момент ключі та значення в словнику, що виходить, розходяться. Наприклад, ви б зробили початкове перетворення, а потім замінили деякі значення на щось інше. Якщо ключі та значення завжди будуть однаковими, HashSet<String>це забезпечить набагато кращу відповідність вашій ситуації:

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

це не вдасться, якщо список схожий на string1, string2, string3, string1
Pranay Rana

3
@PranayRana Так, було б. Ви можете додати .Distinct()після, listщоб уникнути цього.
dasblinkenlight

Дякую. Я пропустив функцію ToDictionary. Дякую всім, хто в основному дав однакову відповідь. Я підтримав усіх, але можу прийняти лише одну відповідь. Цей був лише один із доданим кодом Distinct, тому, на мою думку, був найбільш повним.
Джонстер

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>>, тому у вас буде список різних ключів з кожним рядковим екземпляром під ним.


це не вдасться, якщо список схожий на string1, string2, string3, string1
Pranay Rana

1

Використовуючи ToDictionary:

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

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


0

Ви можете використовувати:

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

0

EDIT

ще один спосіб поводження з дублікатами - це ви можете зробити так

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.