Mam listę obiektów Person. Chcę przekonwertować na słownik, w którym kluczem jest imię i nazwisko (połączone), a wartością jest obiekt Person.
Problem polega na tym, że mam kilka zduplikowanych osób, więc jeśli użyję tego kodu, to wybucha:
private Dictionary<string, Person> _people = new Dictionary<string, Person>();
_people = personList.ToDictionary(
e => e.FirstandLastName,
StringComparer.OrdinalIgnoreCase);
Wiem, że to brzmi dziwnie, ale na razie nie obchodzą mnie nazwy duplikatów. Jeśli jest wiele nazw, chcę tylko jedną. Czy w ogóle mogę napisać ten kod powyżej, aby pobierał tylko jedną z nazw i nie wysadzał się na duplikatach?
c#
linq
dictionary
leora
źródło
źródło
Dictionary<string, List<Person>>
(lub odpowiednika).Distinct
Odpowiedzi:
Oto oczywiste rozwiązanie niezwiązane z linq:
źródło
Rozwiązanie LINQ:
Jeśli wolisz rozwiązanie inne niż LINQ, możesz zrobić coś takiego:
źródło
Rozwiązanie Linq używające Distinct () i bez grupowania to:
Nie wiem, czy jest ładniejsze niż rozwiązanie LukeHa, ale też działa.
źródło
To powinno działać z wyrażeniem lambda:
źródło
personList.Distinct().ToDictionary(i => i.FirstandLastName, i => i);
Możesz również użyć
ToLookup
funkcji LINQ, której możesz następnie używać prawie zamiennie ze słownikiem.Zasadniczo zrobi to GroupBy w odpowiedzi LukeH , ale da hash , który zapewnia słownik. Tak więc prawdopodobnie nie musisz konwertować go na słownik, ale po prostu użyj
First
funkcji LINQ, gdy potrzebujesz uzyskać dostęp do wartości klucza.źródło
Możesz utworzyć metodę rozszerzającą podobną do ToDictionary (), z tą różnicą, że zezwala na duplikaty. Coś jak:
W takim przypadku, jeśli istnieją duplikaty, wygrywa ostatnia wartość.
źródło
Aby poradzić sobie z eliminacją duplikatów, zaimplementuj metodę,
IEqualityComparer<Person>
która może być używana wDistinct()
metodzie, a wtedy uzyskanie słownika będzie łatwe. Dany:Pobierz słownik:
źródło
źródło
W przypadku, gdy chcemy, aby wszystkie osoby (zamiast tylko jednej osoby) znajdowały się w zwracanym słowniku, możemy:
źródło
Problem z większością innych odpowiedzi jest to, że oni używają
Distinct
,GroupBy
alboToLookup
, co stwarza dodatkowy słownik pod maską. Equally ToUpper tworzy dodatkowy ciąg. Oto, co zrobiłem, co jest prawie dokładną kopią kodu Microsoftu, z wyjątkiem jednej zmiany:Ponieważ zestaw indeksatora powoduje dodanie klucza, nie zostanie zgłoszony, a także przeprowadzi tylko jedno wyszukiwanie klucza. Możesz też nadać mu
IEqualityComparer
npStringComparer.OrdinalIgnoreCase
źródło
Zaczynając od rozwiązania Carra możesz również napisać to jako:
źródło