Wybierz słownik <T1, T2> z LINQ

171

Użyłem słowa kluczowego „select” i metody rozszerzenia, aby zwrócić za IEnumerable<T>pomocą LINQ, ale muszę zwrócić typ ogólny Dictionary<T1, T2>i nie mogę tego rozgryźć. W przykładzie, którego się tego nauczyłem, użyłem czegoś w formie podobnej do poniższej:

IEnumerable<T> coll = from x in y 
    select new SomeClass{ prop1 = value1, prop2 = value2 };

Zrobiłem to samo z metodami rozszerzającymi. Założyłemże skoro elementy w a Dictionary<T1, T2>mogą być iterowane tak KeyValuePair<T1, T2>, że mogłem po prostu zamienić "SomeClass" w powyższym przykładzie na " new KeyValuePair<T1, T2> { ...", ale to nie zadziałało (Klucz i Wartość zostały oznaczone jako tylko do odczytu, więc nie mogłem skompilować tego kodu ).

Czy to możliwe, czy muszę to zrobić w kilku krokach?

Dzięki.

Bogaty
źródło

Odpowiedzi:

284

Metody rozszerzeń zapewniają również rozszerzenie ToDictionary . Jest dość prosty w użyciu, ogólne użycie polega na przekazaniu selektora lambda dla klucza i pobraniu obiektu jako wartości, ale można przekazać selektor lambda zarówno dla klucza, jak i wartości.

class SomeObject
{
    public int ID { get; set; }
    public string Name { get; set; }
}

SomeObject[] objects = new SomeObject[]
{
    new SomeObject { ID = 1, Name = "Hello" },
    new SomeObject { ID = 2, Name = "World" }
};

Dictionary<int, string> objectDictionary = objects.ToDictionary(o => o.ID, o => o.Name);

Wtedy objectDictionary[1]będzie zawierać wartość „Hello”

Quintin Robinson
źródło
44
var dictionary = (from x in y 
                  select new SomeClass
                  {
                      prop1 = value1,
                      prop2 = value2
                  }
                  ).ToDictionary(item => item.prop1);

Zakładając, że SomeClass.prop1jest to pożądane Keydla słownika.

albertein
źródło
27
.ToDictionary(item => item.prop1, item => item.prop2);by wyraźnie ustawić wartość również.
finoutlook
42

Zbiór KeyValuePairjest jeszcze bardziej wyraźny i działa bardzo dobrze.

Dictionary<int, string> dictionary = objects
    .Select(x=> new KeyValuePair<int, string>(x.Id, x.Name))
    .ToDictionary(x=>x.Key, x=>x.Value);
Antoine Meltzheim
źródło
Czy można usunąć .ToDictionary (x => x.Key, x => x.Value); i zastąpić nową KeyValuePair nowym słownikiem?
Amir Hajiha
@ AmirNo-Family Mylisz się. Metoda Select (x => x ...) wykonuje rzutowanie dla każdego elementu kolekcji obiektów . Zatem zastąpienie nowego KeyValuePair nowym słownikiem stworzyłoby słownik słowników. Nie sądzę, że to jest to, do czego zmierzasz.
Antoine Meltzheim
Mam listę Dictionary <string, string> i próbowałem użyć na nich wyboru, ale zgłasza błąd kompilacji.
Amir Hajiha