Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LINQ to flatten lists while capturing the index

I have a List<List<List<Foo>>> and I would like to flatten this to List<new {Foo, Ndx}> where Ndx is the index from the outermost List. For example, if I had something like:

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

I might end up with Ndx of 0 for "a", "b", & "c" and 1 for "x" & "y". Someone have a LINQ solution?

like image 641
user1096354 Avatar asked Nov 26 '25 15:11

user1096354


1 Answers

Bit fiddly, but you can do it like this:

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

A compilable version is:

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

EDIT: As @sll points out, this solution requires .NET 4 due to the use of Tuple. It wouldn't be too hard to adapt though if necessary.

like image 65
Stuart Golodetz Avatar answered Nov 29 '25 03:11

Stuart Golodetz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!