Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LINQ:如何将嵌套的层次对象转换为展平对象_Linq - Fatal编程技术网

LINQ:如何将嵌套的层次对象转换为展平对象

LINQ:如何将嵌套的层次对象转换为展平对象,linq,Linq,如何使用LINQ将嵌套层次对象转换为展平对象?我知道我们可以很容易地使用foreach循环来实现这一点。但是我想知道是否有一种方法可以用LINQ来写 class Person{ public int ID {get;set} public string Name {get;set} public List<Person> Children {get;} } 我喜欢将这些数据转换成如下所示的扁平格式 1 | Jack 2 | Rose 3 | Paul 我

如何使用LINQ将嵌套层次对象转换为展平对象?我知道我们可以很容易地使用foreach循环来实现这一点。但是我想知道是否有一种方法可以用LINQ来写

class Person{
   public int ID {get;set}
   public string Name {get;set}
   public List<Person> Children {get;}
}
我喜欢将这些数据转换成如下所示的扁平格式

1 | Jack 

2 | Rose 

3 | Paul

我们如何使用Linq呢?

如果你想让它压扁任意深度的人,我建议如下:

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;
}
或者

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

但这对我来说似乎有点不必要。

这是一种很好的、通用的、可重用的扩展方法:

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;
                }
            }
        }
    }
}

一个小缺点是它没有在列表中包含原始父级,您需要这样做。

当然,lambdas可以自己调用。下面是使用递归lambda的Fibonacci:
Func fib=null;fib=i=>我说过“匿名lambdas不能调用它们自己”,这就是为什么他不能编写一个表达式来返回他想要的值——他需要声明一个命名函数来递归。因此,通过将匿名的东西放入变量中,它就不再是匿名的了?例如,
var a=new{X=5}?我仍然将引用的
a
称为匿名类型。微软无条件地这样说,看看第二个例子。几乎所有匿名的东西都必须放在某种命名变量或参数中;否则,代码无法使用它们。这并不意味着它们不是匿名的。我将继续使用“匿名”一词来表示“不通过名称识别”。在您的示例中,类型是匿名的,但对象不是匿名的。您只是以一种我认为不常见的方式使用词。我求助于维基百科页面:“在编程语言理论中,匿名函数(也是函数常量、函数文字或lambda函数)是一个定义的函数(或子例程),可能被调用,而不受标识符的约束。”我不想用“名称”这个词来形容“对象没有名称”,因此,我们在这一点上仍有分歧。
yield return parent;
    foreach (Person relative in parent.Children.SelectMany(GetFamily))
        yield return relative;
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);