2011-06-30 138 views
2

可以說我有對象的平面列表,每個都有一個人的名字,他們是一個單一的角色,就像這樣:有沒有更好的LINQ查詢來做到這一點?

 var People = new[] { 
      new PersonRole(){ Name = "Adam", Role = "R1" }, 
      new PersonRole(){ Name = "Adam", Role = "R2" }, 
      new PersonRole(){ Name = "Adam", Role = "R3" }, 
      new PersonRole(){ Name = "Bob", Role = "R1" }, 
     }; 

現在,有一個直接的方式進入這個一個基於名稱和角色(顯然)的Dictionary<string, List<string>>。我分兩步做,如下圖,但我必須認爲有一個更直接的方法。

Dictionary<string, List<string>> resultLookup = 
    People.Select(p => p.Name).Distinct().ToDictionary(str => str, str => new List<string>()); 

People.ForEach(p => resultLookup[p.Name].Add(p.Role)); 

謝謝!

+0

你選擇使用詞典<字符串,列表>,因爲一個人可以有多個角色?我會認爲只是Dictionary 會更好。或者將Role屬性作爲Role(s)數組。 –

+0

是的,一個人可以有多個角色 –

回答

2
var dict = People.ToLookup(p=>p.Name, p=>p.Role) 
    .ToDictionary(it=>it.Key, it=>it.ToList()); 
+0

這是最好的解決方案! –

+0

哦,我 - 那很好 - 我只是覺得我忘了GroupBy。 –

5
Dictionary<string, List<string>> dictionary = people.GroupBy(p => p.Name).ToDictionary(g => g.Key, g => g.Select(p => p.Role).ToList()); 

未經檢驗的,但我認爲應該工作...現在

編輯進行了測試,並在事實上的工作,確實。

+0

GroupBy - 這是我無法想到的 - 多麼尷尬,但謝謝 –

+1

@亞當:不客氣。不知道你爲什麼覺得這很尷尬。這就是爲什麼,提出你不確定的問題。 – BFree

3

這應做到:

var people = new[] { 
    new { Name = "Adam", Role = "R1" }, 
    new { Name = "Adam", Role = "R2" }, 
    new { Name = "Adam", Role = "R3" }, 
    new { Name = "Bob", Role = "R1" }, 
}; 

var r = from p in people 
     group p by p.Name 
     into g 
     select new { 
      Name = g.Key, 
      Roles = g.Select(p => p.Role).ToList() 
     }; 

var d = r.ToDictionary(k => k.Name, e => e.Roles); 
+0

你忘記了'ToList'調用,OP指定他想要一個包含角色的'List '。 – CodesInChaos

+0

確實如此,已更正。 –

+0

+1不包裝查詢樣式linq在圓括號使用'.ToDictionary'。當你將這些部分分成另一行/任務時,它就更加清晰了。 – Shibumi

1
var result = People.GroupBy(a => a.Name).ToDictionary(a => a.First().Name, b => b.Select(c => c.Role).ToList()); 
1
People 
.GroupBy(p => p.Name) 
.ToDictionary(p => p.Key, p => p.Select(pr => pr.Role).ToList()) 
相關問題