让我们说我有三个清单:
A = {“b”,“c”,“d”,“x”,“y”,“z”}
B = {“a”,“e”,“i”}
我想生成从两个列表中选择一个元素的所有组合。
对于2个列表,这很容易(pseuodo-ish代码):
combinations = []
for a in A:
for b in B:
combinations += [a, b]
但是,如果列表的数量未知,该怎么办? 我想用C#扩展方法以某种方式推广这个。
方法签名将是这样的:
public static IEnumerable<IEnumerable<T>> Combination<T>(this IEnumerable<IEnumerable<T>> elements)
修改 我正在寻找笛卡尔积,感谢您的澄清。
答案 0 :(得分:1)
如果你只是平面组合,并且你有一组这些套装,你应该能够在套装上使用SelectMany。
public static IEnumerable<[T]> Combination<T>(this IEnumerable<IEnumerable<T>> elements)
{
return elements.Select(
e => elements.Except(e).SelectMany( t => new T[e,t] )
);
}
答案 1 :(得分:0)
假设您希望所有组合包括具有不同顺序的重复元素的组合,这基本上是现有方法SelectMany
所做的。
使用查询表达式和匿名对象获取所有组合相当容易。这是一个例子:
var combinations = from a in allAs
from b in allBs
select new { A = a, B = b };
一举这样做(使用建议的Combination
方法)至少需要你:
Zip
方法的签名)Tuple<T, T>
但话又说回来,它实际上只是取代了笛卡尔积(SelectMany
)和投影(Select
)的用法,两者都已经存在。