例如,如果我有两个列表,我会这样做:
foreach (Item item1 in lists[0])
foreach (Item item2 in lists[1])
// Do something with item1 and item2
或者,如果我有三个,我会做
foreach (Item item1 in lists[0])
foreach (Item item2 in lists[1])
foreach (Item item3 in lists[2])
// Do something with item1, item2, and item3
但如果我在编译时不知道lists
集合中有多少列表,我怎样才能轻松迭代每个排列?
C#解决方案是理想的解决方案,但是任何演示合适算法的语言的解决方案都会很方便。
一个好的二维示例是电子表格中的列列表和行列表,我需要在每个单元格上进行处理。然而,这是一个n维问题。
答案 0 :(得分:4)
Eric Lippert在这个问题上有一个wonderful article。
我高度建议阅读这篇文章,因为它描述了你可以得出结果的过程,但最后得到的代码简短而甜蜜:
(从链接逐字复制)
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}));
}
答案 1 :(得分:1)
public static IEnumerable<T[]> IterateOverLists<T>(this IList<IEnumerable<T>> lists )
{
var array = new T[lists.Count];
return IterateOverLists( lists, array, 0 );
}
private static IEnumerable<T[]> IterateOverLists<T>(this IList<IEnumerable<T>> lists, T[] array, int index)
{
foreach (var value in lists[index])
{
array[index] = value;
if (index == lists.Count - 1)
{
// can make a copy of the array here too...
yield return array;
}
else
{
foreach (var item in IterateOverLists(lists, array, index + 1))
{
yield return item;
}
}
}
}
如果你的一个清单是空的,它会杀死整个东西,但你应该可以解决这个问题......
答案 2 :(得分:0)
for (int i = 0; i < lists.Length; i++) {
foreach (Item item in lists[i]) {
....
}
}