11

リスト内の各 2 要素の組み合わせを反復処理する制御構造を記述する最良の方法は何ですか?

例:

{0,1,2}

コードのブロックを 3 回、それぞれで 1 回ずつ実行したいと考えています。

{0,1}
{1,2}
{0,2}

私は次のことを試しました

foreach (int i in input)
{
    foreach (int j in input.Where(o => o != i))
    {
        //Execute code
    }
}

ただし、リストに同じ要素が 2 つある場合、これは機能しません。と

{0,2,0}

0私はまだ要素とを比較したいと思い0ます。値は無関係です。

4

2 に答える 2

36

次のようなものが必要なようです。

for (int i = 0; i < list.Count - 1; i++)
{
    for (int j = i + 1; j < list.Count; j++)
    {
        // Use list[i] and list[j]
    }
}

あなたは間違いなくLINQでこれを行うことができます:

var pairs = from i in Enumerable.Range(0, list.Count - 1)
            from j in Enumerable.Range(i + 1, list.Count - i - 1)
            select Tuple.Create(list[i], list[j]);

はっきりとは分かりませんが・・・。

編集:効率は低いが、より明確になる可能性がある別の代替手段:

var pairs = from i in Enumerable.Range(0, list.Count - 1)
            let x = list[i]
            from y in list.Skip(i + 1)
            select Tuple.Create(x, y);
于 2013-06-10T19:57:47.600 に答える
2

C# 7 以降を使用している場合は、このValueTuple型を利用できます。使いやすさとパフォーマンスが向上します。

public static IEnumerable<(T, T)> GetAllPairs<T>(IList<T> source)
{
    return source.SelectMany((_, i) => source.Where((_, j) => i < j),
        (x, y) => (x, y));
}

使用例:

foreach ((int x, int y) in GetAllPairs(new[] { 0, 1, 2 }))
{
    // Execute code
    Console.WriteLine($"Pair: {x}, {y}");
}

出力:

Pair: 0, 1
Pair: 0, 2
Pair: 1, 2
于 2020-05-06T16:53:08.657 に答える