有没有一个很好的LINQ方法来做笛卡尔产品?
我有一个像这样的类结构:
Person Dogs (dog 1, dog 2, etc) Puppies (puppy A, puppy B, etc)
有一个人 他有1..n条狗。 每只狗有1..n只小狗。
我想要一个所有可能的小狗组合的列表,每只狗取一只小狗。 例如:
狗1小狗A狗2小狗狗1小狗A狗2小狗B狗1小狗B狗2小狗狗1小狗B狗2小狗B
如果是在sql表中,我会做类似下面的“乘”表:
select * from puppies a, puppies b where a.parent='dog1' and b.parent='dog2'
有没有一些linq-ish的方式来做这种事情?
非常感谢
如果我明白这个问题,你需要n套小狗的笛卡尔积 。
如果在编译时知道有多less个集合,那么获得笛卡尔积很容易:
from p1 in dog1.Puppies from p2 in dog2.Puppies from p3 in dog3.Puppies select new {p1, p2, p3};
假设dog1有小狗p11,p12,dog2有小狗p21,dog3有小狗p31,p32。 这给你
{p11, p21, p31}, {p11, p21, p32}, {p12, p21, p31}, {p12, p21, p32}
每行都是匿名types。 如果你不知道在编译时有多less套,你可以做更多的工作。 看到我关于这个问题的文章:
http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
和这个StackOverflow问题:
生成所有可能的组合
一旦你有方法CartesianProduct<T>
那么你可以说
CartesianProduct(from dog in person.Dogs select dog.Puppies)
要得到
{p11, p21, p31}, {p11, p21, p32}, {p12, p21, p31}, {p12, p21, p32}
每行都是一系列的小狗。
合理?
dogs.Join(puppies,()=> true,()=> true,(one,two)=> new Tuple(one,two));
您可以执行常规连接,但是select器都返回相同的值,因为我希望所有组合都是有效的。 合并时,将两者合并成一个元组(或您select的不同数据结构)。
leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));
这应该做笛卡尔产品。
如果你想要所有可能的狗和小狗的组合,你会做一个交叉连接:
from dog in Dogs from puppy in Puppies select new { Dog = dog, Puppy = puppy }