【问题标题】:Using LINQ to flatten lists while capturing the index在捕获索引时使用 LINQ 展平列表
【发布时间】:2012-01-19 16:29:46
【问题描述】:

我有一个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 解决方案吗?

【问题讨论】:

  • "我有一个 List>>" ...哇,肯定有更好的结构吗?
  • @Yuck:Yuck 只是你的名字还是你的意见? :)
  • @StuartGolodetz 这实际上是我的名字;我的父母很残忍。
  • 并不意味着粗鲁地顺便说一句 - 只是因为您对数据结构表示厌恶并用“- Yuck”跟进这一事实而感到震惊:)
  • 最终结果集中应该有多少项?

标签: c# .net linq indexing flatten


【解决方案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 指出的那样,由于使用了Tuple,此解决方案需要.NET 4。如有必要,适应也不会太难。

【讨论】:

  • @sll:很公平。我承认我一直是一名 C++ 程序员(我今年早些时候才开始使用 C#),所以我对最新的 .NET 中的新内容或新内容有些迷茫。
【解决方案2】:

应该这样做:

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

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多