C # Konwertuj List <string> na Dictionary <string, string>


117

Może się to wydawać dziwne, ale pomijając to, czy istnieje ładny, zwięzły sposób konwersji listy na słownik, w której każda para klucz-wartość w słowniku jest po prostu każdym ciągiem z listy. to znaczy

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

Przeprowadziłem wiele poszukiwań i na samym Stackoverflow są dosłownie dziesiątki przykładów robienia tego w przeciwnym kierunku, ale nie w ten sposób.

Powodem tego jest to, że mam dwie trzecie komponenty części i ich wymiana jest poza moimi rękami. Jeden zwraca listę adresów e-mail w postaci listy, a drugi wysyła e-maile, w których parametr Do oznacza słownik. Kluczem do słownika jest adres e-mail, a wartością jest ich prawdziwe imię i nazwisko. Jednak nie znam prawdziwego nazwiska, ale nadal działa, jeśli ustawisz prawdziwe imię również na adres e-mail. Dlatego chcę przekonwertować listę na słownik. Można to zrobić na wiele sposobów. Pętla foreach na liście, która dodaje kvp do słownika. Ale ja lubię zwięzły kod i zastanawiałem się, czy istnieje rozwiązanie jednokreskowe.


1
Mam lepsze rozwiązanie z twojego ważnego powodu, szczerze.

2
Możesz chcieć sprawdzić, czy HashSet <> spełnia twoje wymagania, zamiast używać Dictionary <,>.
Greg,

Bardziej bezpośrednio niż powyżsi komentatorzy: Jeśli wyjaśnisz swój powód, dla którego chcesz tego, ktoś prawdopodobnie zaproponuje lepsze rozwiązanie.
Tim S.,

1
Nie ma lepszego rozwiązania. Mam składnik innej firmy, który zwraca listę ciągów znaków. Są to adresy e-mail. Mam inny składnik innej firmy, który wysyła wiadomości e-mail, w których przekazuje Dictionary <string, string>, gdzie kluczem jest adres e-mail, a wartość to prawdziwe imię i nazwisko odbiorcy. Jednak prawdziwą nazwą może być również ponownie adres e-mail, dlatego chcę przekonwertować List <string> na Dictionary <string, string>
Jonnster

Odpowiedzi:


244

Spróbuj tego:

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

Pierwsza lambda pozwala wybrać klucz, druga wybiera wartość.

Możesz się nim bawić i sprawić, by wartości różniły się od klawiszy, na przykład:

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

Jeśli lista zawiera duplikaty, dodaj w Distinct()ten sposób:

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

EDYCJA Aby skomentować ważny powód, myślę, że jedynym powodem, który może być ważny dla takich konwersji, jest to, że w pewnym momencie klucze i wartości w wynikowym słowniku będą się różnić. Na przykład wykonasz początkową konwersję, a następnie zastąpisz niektóre wartości czymś innym. Jeśli klucze i wartości będą zawsze takie same, HashSet<String>zapewni to znacznie lepsze dopasowanie do Twojej sytuacji:

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

to się nie powiedzie, jeśli lista ma postać string1, string2, string3, string1
Pranay Rana.

3
@PranayRana Tak, tak. Możesz dodać .Distinct()po, listaby tego uniknąć.
dasblinkenlight

Dzięki. Brakowało mi funkcji ToDictionary. Dziękuję wszystkim, którzy w zasadzie udzielili tej samej odpowiedzi. Głosowałem za każdym, ale mogę przyjąć tylko jedną odpowiedź. Ten był tylko jednym z dodanym kodem Distinct, więc moim zdaniem był najbardziej kompletny.
Jonnster,

11

Użyj tego:

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

Zobacz MSDN uzyskać więcej informacji, .

Jak wskazuje Pranay w komentarzach, nie powiedzie się to, jeśli element istnieje na liście wiele razy.
W zależności od konkretnych wymagań możesz użyć, var dict = list.Distinct().ToDictionary(x => x);aby uzyskać słownik różnych elementów lub ToLookupzamiast tego:

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

To zwróci, ILookup<string, string>który jest zasadniczo taki sam jak IDictionary<string, IEnumerable<string>>, więc będziesz mieć listę odrębnych kluczy z każdą instancją ciągu pod nią.


to się nie powiedzie, jeśli lista ma postać string1, string2, string3, string1
Pranay Rana.

1

Używając ToDictionary:

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

Jeśli jest możliwe, że dowolny ciąg może się powtórzyć, albo wykonaj Distinctwywołanie najpierw na liście (aby usunąć duplikaty), albo użyj, ToLookupktóry pozwala na wiele wartości na klucz.


0

Możesz użyć:

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

0

EDYTOWAĆ

Innym sposobem radzenia sobie z duplikatem jest to, że możesz to zrobić

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

lub


łatwy sposób to zrobić

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

ale upewnij się, że żaden ciąg się nie powtarza ... znowu inny powyższy kod nie będzie działał dla Ciebie

jeśli istnieje ciąg, to się powtarza, niż lepiej zrobić to w ten sposób

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

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.