我有一组值,例如{ 0, 1, 2 } 可以处于两种状态之一 { 0, 1 }。
有没有一种简单的方法(也许使用 linq 查询)来获取 { value, state } (其中 value 是唯一的)的所有组合的列表,以便我得到如下结果:
{
{ { 0, 0 }, { 1, 0 }, { 2, 0 } },
{ { 0, 0 }, { 1, 0 }, { 2, 1 } },
{ { 0, 0 }, { 1, 1 }, { 2, 0 } },
{ { 0, 0 }, { 1, 1 }, { 2, 1 } },
{ { 0, 1 }, { 1, 0 }, { 2, 0 } },
{ { 0, 1 }, { 1, 0 }, { 2, 1 } },
{ { 0, 1 }, { 1, 1 }, { 2, 0 } },
{ { 0, 1 }, { 1, 1 }, { 2, 1 } },
}
“值”数组可以有不同的大小,但它们只能处于两种状态之一。
(这不完全是笛卡尔积,我不确定可以用什么术语来描述它,所以不知道要谷歌什么)。
谢谢!
最佳答案
它是笛卡尔积的笛卡尔积:
var groups = from x in
(from v in values
from s in states
select new {v,s})
group x by x.v into gx
select gx;
var perms = from a in groups[0]
from b in groups[1]
from c in groups[2]
select new {a,b,c};
groups 查询生成一个 Lookup(概念上是一个只读的 IEnumerables 字典),其中包含所有值和状态(6 个元素)的简单笛卡尔积,按它们的值分组。然后,第二个查询生成笛卡尔积的元素的笛卡尔积,一次取三个元素,一个来自 Lookup 中的每个组。
要在未知数量的维度上进行这项工作会很棘手;如果你不是绝对必须让它那样工作,我会避免它。我认为最优雅的方法是为 System.Tuple 泛型类定义一组扩展方法:
public static Tuple<T1,T2> Append(this Tuple<T1> tuple, T2 addend)
{
return Tuple.Create(tuple.Item1, addend);
}
public static Tuple<T1,T2, T3> Append(this Tuple<T1,T2> tuple, T3 addend)
{
return Tuple.Create(tuple.Item1, tuple.Item2, addend);
}
...
然后,您可以获取这些帮助器并在第二个查询的循环版本中使用它们:
var perms = from a in groups[0] 选择 Tuple.Create(a);
foreach(var group in groups.Skip(1)) perms = 来自 perms 来自b组 选择 a.Append(b);
这将生成所需长度的可枚举元组,其中包含在第一个查询中生成的匿名类型的元素(如果您愿意,可以将其重构为生成强类型的 2 项元组)。使用 perms 集合变量来引用不断增长的元组的集合时,您可能会遇到问题;这是棘手的部分。
关于c# 与 linq 的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5410173/