编写将遍历列表中每个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}
我仍然希望比较元素0
和0
。价值无关紧要。
答案 0 :(得分:26)
听起来你可能想要这样的东西:
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)
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);
答案 1 :(得分:1)
如果您使用的是C#7或更高版本,则可以利用ValueTuple
类型。它提供了increased usability and performance。
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