1

複数のリストを取り、次の方法でそれらを組み合わせるメソッドまたは拡張メソッドを構築したいと思います。

2つのリストがあるとしましょう:

        int[] list1 =  {3, 1, 2};
        int[] list2 =  {5, 4 };

結果として、次のような配列のリストが期待されます。

[1,4]
[1,5]
[2,4]
[2,5]
[3,4]
[3,5]

結果の配列リストの列数は、渡されたリストの量によって決まり、両方の列をソートする必要があります。行数は、(リスト A の長さ) * (リスト B の長さ) * (リスト N の長さ) です。

この例では、3 * 2 = 6 行です。2 列 (入力リストが 2 つあるため)。

linq でこれを行うエレガントな方法は何でしょうか?

ありがとう!

4

3 に答える 3

3

クロスジョインしてみる

int[] list1 =  {3, 1, 2};
int[] list2 =  {5, 4 }; 

var result = (from l1 in list1
             from l2 in list2
             select new [] {l1, l2}).ToList()
于 2013-10-22T15:36:40.510 に答える
2

使用SelectMany:

var combinations = list1.SelectMany(i1 => list2.Select(i2 => new[] { i1, i2 }));

または、必要に応じて

var combinations = list1.SelectMany(i1 => list2, (i1, i2) => new[] { i1, i2 });

結果を特定の順序で取得したい場合は、これをフォローアップすることができますOrderByetc.

于 2013-10-22T15:36:25.783 に答える
2

クレジットは、適切な情報源を示してくれた @Jon と、彼の巧妙なソリューションに対して @EricLippert に贈られました。

    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct =
          new[] { Enumerable.Empty<T>() };
        return sequences.Aggregate(
          emptyProduct,
          (accumulator, sequence) =>
            from accseq in accumulator
            from item in sequence
            select accseq.Concat(new[] { item }));
    }

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

int と文字列でうまく動作します:

        string[] list1 =  {"1", "2", "3"};
        string[] list2 =  { "4","5" };

        var lists = new List<string[]>(){list1,list2};

        var result = lists.CartesianProduct();
于 2013-10-22T16:10:55.017 に答える