2009-12-21 79 views
14

如何使用LINQ將嵌套的分層對象轉換爲扁平化對象?我知道我們可以很容易地使用foreach循環來實現這一點。但我想知道是否有方法在LINQ中編寫它。LINQ:如何將嵌套的分層對象轉換爲扁平對象

class Person{ 
    public int ID {get;set} 
    public string Name {get;set} 
    public List<Person> Children {get;} 
} 

數據:

ID : 1 

Name : Jack 

Children 

2 | Rose 

3 | Paul 

我想這個數據轉換成扁平化的格式如下圖所示。

1 | Jack 

2 | Rose 

3 | Paul 

我們怎麼用Linq做到這一點?

回答

17

如果你想讓它變平的人任意深樹,我建議如下:

public IEnumerable<Person> GetFamily(Person parent) 
{ 
    yield return parent; 
    foreach (Person child in parent.Children) // check null if you must 
     foreach (Person relative in GetFamily(child)) 
      yield return relative; 
} 

是不是真的與LINQ縮短這個沒有什麼好的辦法,因爲匿名的lambda不能打電話自己沒有遞歸執行Y.你可以 「減少」 上面的方法

return parent.Children.SelectMany(p => GetFamily(p)) 
         .Concat(new Person[] { parent }); 

或可替代

yield return parent; 
    foreach (Person relative in parent.Children.SelectMany(GetFamily)) 
     yield return relative; 

但這對我來說似乎沒有必要。

+0

當然lambda可以自稱。這是Fibonacci使用遞歸lambda:'Func fib = null; fib = i => i <= 1? i:fib(i-1)+ fib(i-2);' – 2012-08-27 12:36:02

+1

我說「匿名* lambda不能調用自己」,這就是爲什麼他不能寫一個表達式來返回他想要的值 - - 他需要聲明一個命名的函數來遞歸。 – mquander 2012-08-28 03:16:10

+0

因此,通過在變量中放置匿名內容,它不再是匿名的?例如。 'var a = new {X = 5};'?我仍然會調用'a'引用一個匿名類型。 Microsoft無條件地表示[「lambda表達式是匿名函數」](http://msdn.microsoft.com/zh-cn/library/bb397687.aspx),並查看[匿名方法]的第二個示例(http: //msdn.microsoft.com/en-us/library/0yw3tz5k.aspx)。幾乎所有的匿名都必須放在某種指定的變量或參數中;否則它們不能被代碼使用。這並不意味着他們不是匿名的。 – 2012-08-28 08:07:43

9

這是一個很好的,通用的,可重用的擴展方法:

static public IEnumerable<T> Descendants<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> descendBy) 
{ 
    if (!source.IsNullOrEmpty()) 
    { 
     foreach (T value in source) 
     { 
      yield return value; 

      if (!descendBy(value).IsNullOrEmpty()) 
      { 
       foreach (T child in descendBy(value).Descendants<T>(descendBy)) 
       { 
        yield return child; 
       } 
      } 
     } 
    } 
} 

在上述情況下,使用這樣的:

var allChildren = parent.Children.Descendants(p => p.Children); 

一個次要尼特的是,它不包括原父母在列表中,你需要這樣做。

相關問題