有没有好的 LINQ 方法来计算笛卡尔积?

发布于 2024-09-30 08:46:55 字数 452 浏览 5 评论 0原文

我有这样的班级结构:

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-ish 方法可以做这种事情???

非常感谢

I have a class structure like so:

Person
Dogs (dog 1, dog 2, etc)
Puppies (puppy A, puppy B, etc)

There is one person. He has 1..n dogs. Each dog has 1..n puppies.

I want a list of all the possible combination of puppies, taking 1 puppy from each dog. Eg:

dog 1 puppy A, dog 2 puppy A
dog 1 puppy A, dog 2 puppy B
dog 1 puppy B, dog 2 puppy A
dog 1 puppy B, dog 2 puppy B

If it was in sql tables, i'd do something like the following to 'multiply' the tables:

select * from puppies a, puppies b where a.parent='dog1' and b.parent='dog2'

Is there some linq-ish way to do this kinda thing???

Thanks so much

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

这个俗人 2024-10-07 08:46:56

<罢工>
dogs.Join(puppies, () => true, () => true, (one, Two) => new Tuple(one, Two));

你可以进行常规连接,但是选择器都返回相同的值,因为我希望所有组合都有效。组合时,将两者放入一个元组(或您选择的不同数据结构)中。

leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));

这应该执行笛卡尔积。


dogs.Join(puppies, () => true, () => true, (one, two) => new Tuple(one, two));

You can do a regular join, but the selectors are both returning the same value, because I want all combinations to be valid. When combining, put both into one tuple (or a different data structure of your choosing).

leftSide.SelectMany((l) => rightSide, (l, r) => new Tuple(l, r));

This should do a Cartesian product.

冷︶言冷语的世界 2024-10-07 08:46:56

如果您想要狗和小狗的所有可能组合,您可以进行交叉连接:

from dog in Dogs
from puppy in Puppies
select new
{
    Dog = dog,
    Puppy = puppy
}

If you want all possible combinations of dog and puppy, you would do a cross join:

from dog in Dogs
from puppy in Puppies
select new
{
    Dog = dog,
    Puppy = puppy
}
凉世弥音 2024-10-07 08:46:56

    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);
    }


    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);
    }

花间憩 2024-10-07 08:46:56

我喜欢 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);

I like the idea of McKay, full sample would look like below.

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);
风追烟花雨 2024-10-07 08:46:55

如果我理解这个问题,你想要 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,那么你就可以说

CartesianProduct(from dog in person.Dogs select dog.Puppies)

get

{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}

其中每一行都是小狗的序列。

有道理吗?

If I understand the question, you want the Cartesian Product of n sets of puppies.

It is easy to get the Cartesian Product if you know at compile time how many sets there are:

from p1 in dog1.Puppies
from p2 in dog2.Puppies
from p3 in dog3.Puppies
select new {p1, p2, p3};

Suppose dog1 has puppies p11, p12, dog2 has puppy p21, and dog3 has puppies p31, p32. This gives you

{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}

Where each row is an anonymous type. If you do not know at compile time how many sets there are, you can do that with slightly more work. See my article on the subject:

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

and this StackOverflow question:

Generating all Possible Combinations

Once you have the method CartesianProduct<T> then you can say

CartesianProduct(from dog in person.Dogs select dog.Puppies)

to get

{p11, p21, p31},
{p11, p21, p32},
{p12, p21, p31},
{p12, p21, p32}

Where each row is a sequence of puppies.

Make sense?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文