C# 生成n元笛卡尔积示例
我发现Eric Lippert的帖子适合我遇到的一个特殊问题 问题是我不知道我应该如何在2+数量的收藏中使用它 拥有C# 生成n元笛卡尔积示例,c#,.net,linq,cartesian-product,C#,.net,Linq,Cartesian Product,我发现Eric Lippert的帖子适合我遇到的一个特殊问题 问题是我不知道我应该如何在2+数量的收藏中使用它 拥有 var collections = new List<List<MyType>>(); foreach(var item in somequery) { collections.Add( new List<MyType> { new MyType { Id = 1} .. n } ); } 示例
var collections = new List<List<MyType>>();
foreach(var item in somequery)
{
collections.Add(
new List<MyType> { new MyType { Id = 1} .. n }
);
}
示例代码已经能够进行“n”笛卡尔乘积(在本例中为3)。您的问题是,当您需要一个
IEnumerable
IEnumerable结果=集合
.Select(list=>list.AsEnumerable())
.CartesianProduct();
由于列表
是IEnumerable
,因此使用Eric的解决方案可以解决您的问题,如下所示:
var collections = new List<List<MyType>>();
var product = collections.CartesianProduct();
foreach(var collection in product)
{
// a single collection of MyType items
foreach(var item in collection)
{
// each item of type MyType within a collection
Console.Write(item);
}
}
@EricLippert的扩展方法的可能副本比那些可能副本中的任何解决方案都更容易理解(至少对我来说)和简洁。无需使用AsEnumerable(),因为每个列表都已经是一个IEnumerable,请参阅:@Infinum不完全。。。CartesianProduct方法采用
IEnumerable
如果不调用AsEnumerable
,则存在不兼容的IEnumerable
。
var arr1 = new[] {"a", "b", "c"};
var arr2 = new[] { 3, 2, 4 };
var result = from cpLine in CartesianProduct(
from count in arr2 select Enumerable.Range(1, count))
select cpLine.Zip(arr1, (x1, x2) => x2 + x1);
IEnumerable<IEnumerable<MyType>> result = collections
.Select(list => list.AsEnumerable())
.CartesianProduct();
var collections = new List<List<MyType>>();
var product = collections.CartesianProduct();
foreach(var collection in product)
{
// a single collection of MyType items
foreach(var item in collection)
{
// each item of type MyType within a collection
Console.Write(item);
}
}
var product =
collections
.CartesianProduct()
.Select(xs => xs.Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString()), sb => sb.ToString()));
foreach(var collectionAsString in product)
{
Console.WriteLine(collectionAsString);
}