2011-05-10 84 views
4

我有人對象和人有屬性組,使他們屬於不同的羣體。 我想獲取列表並將其放置在一個對象中的GrouppedPeople,其中將有List coll。一個coll元素只包含屬於同一組的人員。linq對象分組

所以,如果我有3人:

List<People>(){new People{Name="Test", Group = "Group1"}, 
       new People{Name="SameGroup", Group = "Group1"}, 
       new People{Name="Other", Group = "OtherGroup"}} 

我需要有2個GrouppedPeople的集合。首先包含Test和SameGroup,第二個包含Other(由Group屬性分組)。我試圖用linq做到這一點。

我需要結果爲List類型。 GrouppedPeople是隻有一個類型爲List的屬性的類,所有的元素都來自同一個組。

伊夫想出了這樣的事情:

from oneGroup in mates 
        group oneGroup by oneGroup.pGroupName into g 
        select g; 

其工作正常,但結果對象不是強類型。並且Id喜歡將List作爲結果。有沒有辦法從該匿名對象類型中獲取它?任何其他方式來獲得這一切與linq和保持強大的打字?

+0

你不會失去強打字。匿名類型與名義類型一樣強類型。他們只是沒有名字,就是這樣。 – 2011-05-10 11:31:53

+0

你想要什麼類型的列表?據我所見,您必須在現有代碼中擁有IEnumerable >。 – Egor4eg 2011-05-10 11:34:30

+0

我想List 。 GrouppedPeople是一個包含List 的對象。 – 2011-05-10 13:08:27

回答

4

這將返回匿名類型對象的列表:

var result = (from oneGroup in mates 
        group oneGroup by oneGroup.pGroupName into g 
        select g).ToList(); 

但是,如果你想返回特定類型的對象,你應該創建新類所需的屬性:

public class MateGroup 
{ 
public string Name {get;set;} 
} 

var result = (from oneGroup in mates 
        group oneGroup by oneGroup.pGroupName into g 
        select new MateGroup(){ Name = g.<field_name>}).ToList(); 

UPD:

根據您的意見,請嘗試以下方法:

var result = (from oneGroup in mates 
        group oneGroup by oneGroup.pGroupName into g 
        select new GrouppedPeople(){ People = g.ToList()}).ToList(); 
+0

我想List 。 GrouppedPeople是一個包含List 的對象。我怎麼才能得到它? – 2011-05-10 13:09:41

+0

請嘗試我的更新回答 – 2011-05-10 13:27:32

+0

謝謝,帕維爾,對我來說工作得很好:-) – 2011-05-10 13:38:02

3

你將得到的是一個IEnumerable<IGrouping<string, People>>。該IGrouping<TKey, TElement>接口具有包含您通過分組(在你的情況下,包含在People對象從Group屬性值的字符串)的值Key,你可以枚舉它來獲得屬於該組的項目:

IEnumerable<IGrouping<string, People>> result = from oneGroup in mates 
       group oneGroup by oneGroup.Group into g 
       select g; 

foreach (IGrouping<string, People> grouping in result) 
{ 
    Console.WriteLine("Group: {0}", grouping.Key); 
    foreach (People people in grouping) 
    { 
     Console.WriteLine(" - {0}", people.Name); 
    } 
} 

結果輸出(根據您的樣本數據):

Group: Group1 
- Test 
- SameGroup 
Group: OtherGroup 
- Other 
2

我更喜歡通用的C#語法來編寫LINQ查詢,它比簡單的查詢表單更清晰。

您可以使用結果選擇器將分組結果作爲類型化對象解析。

var resultList = mates 
    .GroupBy(p => p.Group, (g, p) => new B() { Group = g, People = p.ToList() }) 
    .ToList(); 

完整的測試控制檯應用程序代碼:

class People 
{ 
    public string Name; 
    public string Group; 
} 

class GroupedPeople 
{ 
    public string Group; 
    public List<People> People; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var mates = new List<People>() 
     { 
      new People{Name="Test", Group = "Group1"}, 
      new People{Name="SameGroup", Group = "Group1"}, 
      new People{Name="Other", Group = "OtherGroup"} 
     }; 

     var resultList = mates 
      .GroupBy(p => p.Group, (g, p) => new GroupedPeople() { Group = g, People = p.ToList() }) 
      .ToList(); 
    } 
} 

的的GroupBy調用需要兩個參數:

  1. p => p.Group - 這拉姆達(匿名方法)用於返回分組鍵

  2. (g, p) => new GroupedPeople() { Group = g, People = p.ToList() }

    該lambda用於根據組參數創建GroupedPeople對象,第一個參數是由第一個lambda選擇的分組鍵,第二個參數是枚舉與當前組相關的項目。

+0

Viacheslav,請問,請詳細解釋一下嗎?我試圖使用這個代碼,它不適合我。什麼是「g」?我在VS中獲得以下錯誤:無法將lambda表達式轉換爲鍵入IEqualityComparer ,因爲它不是委託類型。 – 2011-05-11 06:36:48

+1

你需要更多的細節?我不知道你是否需要關於lambda或擴展的信息? – 2011-05-11 13:08:03

+0

完美的作品,非常感謝。我希望我能標記2個答案作爲答案。 – 2011-05-13 12:19:06