11

编写将遍历列表中每个 2 元素组合的控制结构的最佳方法是什么?

例子:

{0,1,2}

我想让一段代码运行三次,每次运行一次:

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

我尝试了以下

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

但是,当列表具有两个相同元素时,这将不起作用。和

{0,2,0}

我仍然想比较元素00. 价值无关紧要。

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 回答