列表迭代列表(所有可能的一个方向组合)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了列表迭代列表(所有可能的一个方向组合)相关的知识,希望对你有一定的参考价值。
我有一个表示行和列网格的List<List<string>>
(每个的计数是动态的)。
我需要遍历项目并在一个方向上显示所有可能的组合。
如果我有以下项目,例如:
var items = new List<List<string>>
{
new List<string> {"A", "B", "C", "D"},
new List<string> {"E", "F", "G", "H"},
new List<string> {"I", "J", "K", "L"},
};
输出应该是:
---> *ABCD-ABCH-ABCL-ABGD-ABGH-ABGL-ABKD-ABKH-ABKL-........... IJKL*.
如何迭代列表以实现此结果?
答案
你想要的是转置的笛卡尔积。所以打破它。首先让我们进行转置:
public static List<List<T>> Transpose(
this List<List<T>> sequences)
{
// TODO: throw if sequences is null
// TODO: throw if sequences contains any null
// TODO: throw if the sequences are not all the same length
return Enumerable.Range(0, sequences[0].Count)
.Select(i =>
Enumerable.Range(0, sequences.Count)
.Select(j => sequences[j][i])
.ToList())
.ToList();
}
我们可以从我的答案中获取笛卡尔积:https://stackoverflow.com/a/3098381/88656
现在,你的问题的答案是直截了当的。
IEnumerable<string> combinations = items
.Transpose()
.CartesianProduct()
.Select(sequence => string.Join("", sequence));
请记住,解决这些问题的方法是将问题分解为序列上更基本操作的工作流,然后将扩展方法组合到工作流中。
另一答案
如果您需要N个唯一元素的组合,另一种解决此问题的方法是展平矩阵:
var elementArray = items.SelectMany(x => x).ToList();
这将{{'A', 'B', 'C'}, {'D', 'E', 'F'}}
变成了{'A', 'B', 'C', 'D', 'E', 'F'}
然后使用从another question获取的以下LINQ扩展(将其放在项目的任何位置):
public static class Ex
{
public static IEnumerable<IEnumerable<T>> DifferentCombinations<T> (this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).DifferentCombinations(k - 1).Select(c => (new[] { e }).Concat(c)));
}
}
用作:
var combinations = elementArray.DifferentCombinations(4)
.Select(
l => string.Join("", l.ToArray())
).ToList();
在这种情况下,它将组合长达4(DifferentCombinations(4)
)。
以上是关于列表迭代列表(所有可能的一个方向组合)的主要内容,如果未能解决你的问题,请参考以下文章