使用LINQ将列表扁平化并捕获索引

3

我有一个 List<List<List<Foo>>>,我想将其展平为 List<new {Foo, Ndx}>,其中 Ndx 是最外层列表的索引。例如,如果我有这样的东西:

new List(){
    new List(){
        new List(){ new Foo("a"), new Foo("b")},
        new List(){ new Foo("c")}},
    new List(){
        new List(){ new Foo("x"), new Foo("y")}}}

我可能会得到 "a"、"b" 和 "c" 的 Ndx 值为 0,"x" 和 "y" 的 Ndx 值为 1。有人有 LINQ 解决方案吗?


1
"我有一个 List<List<List<Foo>>>。" ... 哇,肯定有更好的结构可以用吧?" - Yuck
@Yuck:Yuck仅仅是你的名称还是也代表你在这里的看法呢? :) - Stuart Golodetz
@StuartGolodetz 这实际上是我的名字;我父母太残忍了。 - Yuck
顺便说一下,我并不是有意冒犯 - 只是被你表达对数据结构的厌恶,并跟着说“- 呸”所震惊了 :) - Stuart Golodetz
最终结果集应该有多少项? - sll
2个回答

1

有点繁琐,但你可以这样做:

IEnumerable<Tuple<Foo,int>> result =
    tree.SelectMany(
        (L1,i) => L1.SelectMany(
            L2 => L2.Select(
                k => Tuple.Create(k,i)
            )
        )
    );

可编译的版本是:

using System;
using System.Collections.Generic;
using System.Linq;

class Foo
{
    public string s;

    public Foo(string s)
    {
        this.s = s;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var tree = new List<List<List<Foo>>>
        {
            new List<List<Foo>>
            {
                new List<Foo> { new Foo("a"), new Foo("b") },
                new List<Foo> { new Foo("c") }
            },
            new List<List<Foo>>
            {
                new List<Foo> { new Foo("x"), new Foo("y") }
            }
        };

        IEnumerable<Tuple<Foo,int>> result = tree.SelectMany((L1,i) => L1.SelectMany(L2 => L2.Select(k => Tuple.Create(k,i))));
        foreach(var si in result)
        {
            Console.WriteLine(si.Item1.s + ' ' + si.Item2);
        }
    }
}

编辑:正如@sll所指出的那样,这个解决方案需要.NET 4,因为使用了Tuple。不过如果必要的话,适应也不会太难。


@sll:说得好。我承认我一直是C++程序员(今年早些时候才开始接触C#),所以最新的.NET有什么新东西或不同之处对我来说有些模糊。 - Stuart Golodetz

1
这应该可以做到:
var l = new List<List<List<Foo>>>(){
            new List<List<Foo>>(){
                new List<Foo>(){ new Foo("a"), new Foo("b")},
                new List<Foo>(){ new Foo("c")}},
            new List<List<Foo>>(){
                new List<Foo>(){ new Foo("x"), new Foo("y")}}};

var q = l.SelectMany ((x, i) => 
            x.SelectMany (y => 
                y.Select (z => new { z, i })));

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