3

そこにリストのリスト があるとすると、すべてのリストに 0 個以上のアイテムが含まれている可能性がありますが、必ずしもすべて同じ数であるとは限りません。そして、リスト内のすべてのアイテムを含むリストが必要です...しかし、順序を次のようにしたいと思います。最初に、すべてのリストの最初のアイテムから、それらが「スーパーリスト」に表示されるようにします。List<List<T>>

元。

List[0] = { 'Apple', 'Blueberry', 'Cranberry' }
List[1] = { 'Anteater', 'Baboon', 'Camel', 'Dodo'}
List[2] = { 'Albatross', 'Blackbird', 'Chicken'}

result = { 'Apple', 'Anteater', 'Albatross', 'Blueberry', 'Baboon', 
           'Blackbird', 'Cranberry', 'Camel', 'Chicken', 'Dodo' }

(これはアルファベット順ではないことに注意してください。ブルーベリーがヒヒの前になります)

もちろん、空でないリストがある限り、カウンターを使用して「スーパーリスト」をループし、結果リストに項目を 1 つずつ追加することもできます。

int i = 0;
bool done = false;

while (!done)
{
    bool found = false;

    foreach (list l in superlist)
    {
        if (l.Count() > i)
        {
           found = true;
           result.Add(l[i]);
        }
    }

    i++;

    if (!found)
        done = true;
}

ただし、これを行うには、最適化された LINQ 関数を使用する方がはるかに優れています。私はZipGroupBy、およびAggregateを調べてきましたが、それらを機能させることができませんでした。

だから:これをきれいなコードに変えるきれいなLINQ関数、または複数の組み合わせはありますか、それとも現在の関数に固執する(そしておそらく最適化する)必要がありますか?

編集:単純な SelectMany(x => x) も、私のアルゴリズムのように折りたたむのではなく、リストの順序を保持するため、うまくいきません。詳細については、私の最初の質問を参照してください。

4

7 に答える 7

8

あなたが必要SelectMany

var result = lists.SelectMany(x => x.Select((s, inx) => new { s, inx }))
                .GroupBy(x => x.inx)
                .SelectMany(x => x.Select(y => y.s))
                .ToList();

編集

試してみたい方は初期化コードを。

List<List<string>> lists = new List<List<string>>()
        {
            new List<string>(){ "Apple", "Blueberry", "Cranberry" },
            new List<string>(){ "Anteater", "Baboon", "Camel", "Dodo"},
            new List<string>(){ "Albatross", "Blackbird", "Chicken"},
        };

編集2

出力: Apple,Anteater,Albatross,Blueberry,Baboon,Blackbird,Cranberry,Camel,Chicken,Dodo

于 2013-08-23T18:47:57.930 に答える
1

使うだけMyListOfLists.SelectMany(x => x).OrderByDescending(x => x).ToList()

SelectMany は、リストを 1 つにフラット化します。OrderByDescending はその結果に基づいて動作し、結果をアルファベット順に並べます (これが必要だと思います)。ToList次に、実行を強制するために呼び出し、List<string>代わりにを取得しますIEnumerable<string>

于 2013-08-23T18:48:29.167 に答える
0

Enumerable.SelectManyを使用して、リスト内の項目を平坦化し、そこから新しいリストを作成します。

var result = superlist.SelectMany(r=> r).ToList();
于 2013-08-23T18:48:30.680 に答える
0

私はあなたがやろうとしていることを見ます:

var result = input.SelectMany(l => l.Select((o, i) => new { o, i })).GroupBy(o => o.i).OrderBy(g => g.Key).SelectMany(g => g.Select(o => o.o);
于 2013-08-23T19:10:59.477 に答える
0

組み込みの linq 拡張機能を使用して、すべてのリストから最初の要素を選択し、次に 2 番目などを選択する (パフォーマンスとコードの読みやすさの点で) 簡単または最適な方法はありません。whileただし、コードから独自の拡張機能を構築することも、以下に示すようにループが気に入らない場合も可能です。

public static class MyLinqExtensions
{
    public static void MySelect<T>(this IEnumerable<IEnumerable<T>> superlist)
    {
        int index = 0;

        foreach (IEnumerable<T> list in superlist)
        {
            if (index < list.Count())
            {
                yield return list.ElementAt(index);
            }

            index++;
        }
    }
}

最後にEnumerable.Distinct()、結果を呼び出して一意の値を取得できます。

于 2013-08-23T19:00:57.690 に答える