递归列表拍平

41

我可能可以自己写这个代码,但是我尝试编写一个通用的扩展方法,类似于.NET 3.5中引入的其他扩展方法,它将获取一个嵌套的IEnumerable集合(等等)并将其展开为一个IEnumerable。有人有什么想法吗?

具体来说,我在扩展方法的语法上遇到了问题,以便我可以编写展平算法。


你的数据是如何表示的?与XPath一样简单的方法并不存在。 - Ray Hayes
4
没有任何迹象表明这是一道作业问题... - Tim Frey
数据只是普通的对象。 - Matt H
非法程序员:没有明确的内容,但是当问题涉及语法并且没有代码时,很有可能这是一份作业。(但发帖者可以自由删除此信息。) - Jon Ericson
相关(Eric Lippert的使用堆栈处理更大数据结构的解决方案):https://dev59.com/1Ggt5IYBdhLWcg3wxANj#20335369 - Mafii
13个回答

0
class PageViewModel { 
    public IEnumerable<PageViewModel> ChildrenPages { get; set; } 
}

Func<IEnumerable<PageViewModel>, IEnumerable<PageViewModel>> concatAll = null;
concatAll = list => list.SelectMany(l => l.ChildrenPages.Any() ? 
    concatAll(l.ChildrenPages).Union(new[] { l }) : new[] { l });

var allPages = concatAll(source).ToArray();

0
static class EnumerableExtensions
{
    public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> sequence)
    {
        foreach(var child in sequence)
            foreach(var item in child)
                yield return item;
    }
}

可能是这样吗?还是你的意思是它可能会无限地深入下去?


论坛很高兴地继续吃掉这个签名,也许它会起到评论的作用。 public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> sequence) - Torbjörn Gyllebring
好了,它卡在代码和预格式标签上了(这两个都不必要)。 - Derek Park
请注意,由于泛型不变性,您将无法将List<List<int>>传递给该方法 - List<List<int>>不是List<IEnumerable<int>>。这就是为什么我在我的类似代码中有两个类型参数的原因。当然,随着C# 4的推出,这可能会发生改变 :) - Jon Skeet

-1

基本上,您需要在递归函数之外拥有一个主要的IENumerable,然后在递归函数中(伪代码)

private void flattenList(IEnumerable<T> list)
{
    foreach (T item in list)
    {
        masterList.Add(item);

        if (item.Count > 0)
        {
            this.flattenList(item);
        }
    }
}

虽然我不确定您所说的IEnumerable嵌套在IEnumerable中是什么意思...其中包含什么?有多少层嵌套?最终类型是什么?显然我的代码不正确,但我希望它能让您思考。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接