我有类似的类结构:
Person
Dogs (dog 1, dog 2, etc)
Puppies (puppy A, puppy B, etc)
有一个人。他有1只狗。每只狗都有1只小狗。
我想要列出所有可能的小狗组合,从每只狗中取出1只小狗。例如:
狗1小狗A,狗2小狗A 狗1小狗A,狗2小狗B. 狗1小狗B,狗2小狗A. 狗1小狗B,狗2小狗B如果它是在sql表中,我会做类似以下的事情来'乘以'表:
select * from puppies a, puppies b where a.parent='dog1' and b.parent='dog2'
是否有一些linq-ish方式来做这件事???
非常感谢
答案 0 :(得分:79)
如果我理解了这个问题,你需要n套小狗的笛卡尔积。
如果您在编译时知道有多少集合,那么很容易获得笛卡尔积:
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}
每行都是匿名类型。如果您在编译时不知道有多少集,那么您可以稍微多做一些工作。请参阅我关于这个主题的文章:
http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
和这个StackOverflow问题:
Generating all Possible Combinations
获得方法CartesianProduct<T>
之后,您可以说
CartesianProduct(from dog in person.Dogs select dog.Puppies)
获取
{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}
每行都是一系列小狗。
有意义吗?
答案 1 :(得分:18)
<击> dogs.Join(puppies,()=&gt; true,()=&gt; true,(one,two)=&gt; new Tuple(one,two));
您可以进行常规连接,但选择器都返回相同的值,因为我希望所有组合都有效。组合时,将两者放入一个元组(或您选择的不同数据结构)。
leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));
这应该是笛卡尔积。
答案 2 :(得分:13)
如果你想要狗和小狗的所有可能组合,你会做一个交叉连接:
from dog in Dogs
from puppy in Puppies
select new
{
Dog = dog,
Puppy = puppy
}