我有一个像这样的类结构:
Person
Dogs (dog 1, dog 2, etc)
Puppies (puppy A, puppy B, etc)
有一个人。他有 1..n 只狗。每只狗有 1..n 只小狗。
我想要一份所有可能的小狗组合的列表,从每只狗中取出一只小狗。例如:
狗 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 的方法来做这种事情???
非常感谢
如果我理解这个问题,你想要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 问题:
一旦你有了方法
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, (一,二) => new Tuple(一,二));
您可以进行常规连接,但选择器都返回相同的值,因为我希望所有组合都有效。组合时,将两者放入一个元组(或您选择的不同数据结构)中。
leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));
这应该做笛卡尔积。
如果您想要狗和小狗的所有可能组合,您可以进行交叉连接:
from dog in Dogs
from puppy in Puppies
select new
{
Dog = dog,
Puppy = puppy
}
string[] colors = { "Red", "Green", "Blue" };
string[] sizes = { "Small", "Medium", "Large" };
var result = from color in colors
from size in sizes
select new { Color = color, Size = size };
foreach (var item in result)
{
Console.WriteLine(item);
}
我喜欢McKay的想法,完整的示例如下所示。
var r = new Random();
var d = Enumerable.Range(1, 3).ToDictionary(x => Guid.NewGuid(), y => Enumerable.Range(1, 10).Select(z => r.Next()).ToList());
var kvps = d.Keys.SelectMany((key) => d[key], (key, value) => new KeyValuePair<Guid, int>(key, value));
var l = kvps.ToLookup(kvp => kvp.Key, kvp => kvp.Value);