2013-05-18 1 views
1

Если у меня есть класс типаСписка <Info> где информация имеет фамилию и свойство отображение словарь <Лэст Список <First>>

class Info 
{ 
    public Info(string first, string last) { this.First = first; this.Last = last; } 
    string First { get; private set; } 
    string Last { get; private set; } 
} 

и список, например:

var list = new List<Info>(); 
list.Add(new Info("jon", "doe"); 
list.Add(new Info("jane", "doe"); 
list.Add(new Info("bason", "borne"); 
list.Add(new Info("billy", "nomates"); 

И I хотите сопоставить в отсортированный список фамилии со списком первых имен, то есть Dictionary<string,List<string>>, где ключ - это свойство Фамилия, а список - это список свойств имени.

В приведенном выше примере я хотел бы получить { "doe" => { "jon", "jane" }, "borne" => { "jason" }, "nomates" => { "billy" } }.

Можно ли сделать это аккуратно с Linq, и если да, то как бы я это сделал?

+2

Вы упомянули, что хотите его отсортировать, однако ваш пример не отсортирован. Словарь - неупорядоченная коллекция. –

+0

Хорошо заметили - мне не нужна сортировка, только группировка – g18c

ответ

2

Вы можете использовать GroupBy и ToDictionary, чтобы это было сделано:

Во-первых, сделать свои свойства в своем классе общественности, а затем использовать этот код:

Dictionary<string, List<string>> names = list 
    .GroupBy(x => x.Last) 
    .ToDictionary(x => x.Key, x => x.Select(y => y.First).ToList()); 
1

Я обычно предпочитаю используя ILookup<,> для такого рода данных. Вы можете построить его так:

list.ToLookup(e => e.Last, e => e.First); 

Хотя это технически не Dictionary<string,List<string>>, как вы просили, он все равно будет делать большинство вещей, которые вы бы, наверное, хотели сделать.

var firstNamesByLastName = list.ToLookup(e => e.Last, e => e.First); 
foreach(var firstName in firstNamesByLastName["bourne"]) 
{ 
    Console.WriteLine(firstName); // outputs "jason" 
} 

Обратите внимание, что вы не можете изменить ILookup объект. Таким образом, вы не можете добавлять новые имена после их создания. Но тот факт, что вы хотите построить его с LINQ, говорит мне, что вы почти наверняка не собираетесь это делать.

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

// if this used a dictionary, we'd get an exception. 
foreach(var firstName in firstNamesByLastName["unborne"]) 
{ 
    Console.WriteLine(firstName); // outputs "jason" 
} 
+0

Хм, не знал этого. +1 для хорошей альтернативы. – gunr2171

+0

Единственное предостережение в том, что поиск не изменчив. –

Смежные вопросы