【问题标题】:How do I return all of the child objects - I can't get SelectMany to work如何返回所有子对象 - 我无法让 SelectMany 工作
【发布时间】:2012-10-19 17:33:16
【问题描述】:

我有课

    public class Foo
    {
       public IList<Foo> Items { get; set; }
    }

    public class FooList
    {
       public IList<Foo> Items { get; set; }
    }

我希望能够在一个列表中获取所有 Foo 对象,而不是层次结构。

我试过了

    IEnumerable<Foo> result = Items.SelectMany(f =>  f.Items);

但这只是让我获得该特定对象中的项目 - 它不会获得所有子对象中的所有项目。

我也试过

    IEnumerable<Foo> result = Items.SelectMany(t => t)

但我得到了错误:

无法从用法中推断方法“System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable, System.Func>)”的类型参数。尝试明确指定类型参数。

【问题讨论】:

  • 一个 FooList 有一个 foo 列表。每个 Foo 也有一个 foo 列表,每个 foo 都有一个 foo 列表...

标签: linq


【解决方案1】:

在更一般的情况下可以使用类似“扁平化这棵树”的 LINQ 函数是相当容易的:

public static IEnumerable<T> Flatten<T>(
    this IEnumerable<T> source,
    Func<T, IEnumerable<T>> childSelector)
{
    HashSet<T> added = new HashSet<T>();
    Queue<T> queue = new Queue<T>();
    foreach(T t in source)
        if (added.Add(t))
            queue.Enqueue(t);
    while (queue.Count > 0)
    {
        T current = queue.Dequeue();
        yield return current;
        if (current != null)
        {
            IEnumerable<T> children = childSelector(current);
            if (children != null)
                foreach(T t in childSelector(current))
                    if (added.Add(t))
                        queue.Enqueue(t);
        }
    }
}

那么如果你有FooList,你可以使用

var allFoos = myFooList.Items.Flatten(foo => foo.Items);

获取列表中的所有Foos,以及他们的所有孩子和所有他们的孩子和...

【讨论】:

    【解决方案2】:

    假设您有一个名为fooListFooList 实例:

    您需要在FooList 类中定义这样的方法:

    public IEnumerable<Foo> GetRecursiveFoos()
    {
        return Items.Concat(Items.SelectMany(x => x.Items));
    }
    

    然后调用

    IEnumerable<Foo> result = fooList.GetRecursiveFoos();
    

    【讨论】:

    • 这实际上并没有递归。它只会获得最高级别和更高级别。
    • @Rawling 对。我在阅读您的代码时犯了一个错误,对数据结构有错误的印象。
    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2012-07-27
    相关资源
    最近更新 更多