Использование LINQ для выравнивания списков при захвате индекса - PullRequest
3 голосов
/ 13 декабря 2011

У меня есть 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")}}}

Я мог бы получить Ndx, равный 0 для "a", "b", & "c" и 1 для "x" & "y". У кого-нибудь есть решение LINQ?

Ответы [ 2 ]

1 голос
/ 14 декабря 2011

Это должно сделать это:

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 })));
1 голос
/ 14 декабря 2011

Немного странно, но вы можете сделать это так:

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. Адаптировать его было бы не так уж и сложно, если это необходимо.

...