2011-11-11 25 views
0

我有一個正常的GroupBy操作上可枚舉:簡單的方法來在LINQ集合上的GroupBySubElement?

e.GroupBy(i => i.Property) 

但如果i.Property確實是一個集合,我怎麼會掰開收集和使用列表的元素分組關鍵字?

例如,讓我們說我有兩個對象(Z,Y),每有一個列表:

Z: { List = { A, B, C }} 
Y: { List = { B, C, D }} 

現在運行GroupBySubelement(O => o.List)將不會被列表本身組,但會迭代列表並生成以下分組。

{A, {Z}} 
{B, {Z, Y}} 
{C, {Z, Y}} 
{D, {Y} 

這可能嗎?

謝謝!

回答

2

下面是一些例子代碼,達到你想要的東西:

//This is just temporary data. Has the similar structure to what you want. 
var parts = new[] 
       { 
        new 
         { 
          Name = "X", 
          Property = new[] {'A', 'B', 'C'} 
         }, 
        new 
         { 
          Name = "Y", 
          Property = new[] {'B', 'C', 'D'} 
         }, 
        new 
         { 
          Name = "Z", 
          Property = new char[] { } 
         } 
        }; 

var groupedBySub = from part in parts 
        from sub in part.Property 
        group part by sub; 

foreach(var group in groupedBySub) 
{ 
    Console.WriteLine("{0} - {1}", group.Key, string.Join(", ", group.Select(x => x.Name))); 
} 

,輸出:

A - X 
B - X, Y 
C - X, Y 
D - Y 

您還可以在該方法實現這一目標連鎖時尚:

var groupedBySub = parts.SelectMany(part => part.Property, (part, sub) => new {part, sub}).GroupBy(t => t.sub, t => t.part); 

如果你想與該列表是空的捕捉到它:

var groupedBySub = from part in parts 
        from sub in part.Property.DefaultIfEmpty() 
        group part by sub; 

,當取代上面的代碼,使輸出:

這裏的問題的
A - X 
B - X, Y 
C - X, Y 
D - Y 
    - Z 
+0

這似乎工作;我缺少的部分是使用SelectMany和DefaultIfEmpty子句的替代方法。謝謝。 –

0

這會做:

var combinations = e.SelectMany(i => i.List.Select(x => new { x, i })); 
var groups = combinations.GroupBy(c => c.x, c => c.i); 
+0

這會捕獲列表爲空的情況下? –

+0

但是在那種情況下你想要什麼?一個有空鍵的組? – mquander

-1

部分原因是,你不沒有一個好的數據結構:

var z = new List<T>(); // I'm using T here, so let's pretend this is in a generic method 
var y = new List<T>(); 
// add a bunch of stuff 

真的沒有任何算法可以讓你得到你想要的,因爲變量Z和Y並不真正爲數據結構所知,只有comiler。

但是,如果你有一個數據結構是這樣的:

var allOfTheLists = new Dictionary<T, List<T>>(); 

然後,您可以使用這樣的事情打破它了:

var explodedList = allOfTheLists.SelectMany((pair) => pair.Value.Select((item) => new { pair.Key, item})); 
var grouping = explodedList.GroupBy((explodedItem) => explodedItem.item); 
相關問題