如何使用 LINQ 获得某些字段不同的组合

发布于 2024-11-06 14:42:05 字数 543 浏览 1 评论 0 原文

我需要一个 LINQ 查询来获取以下结构的所有组合(按名称区分):

var keys = new[]
{
    new { Name = "A", Value = "1" },
    new { Name = "A", Value = "2" },
    new { Name = "B", Value = "3" },
    new { Name = "B", Value = "4" },
    // etc
};

我需要获取:

{A1, B3} {A1, B4} {A2, B3} {A2, B4} // etc

其中 A1-B4 我的意思是整个项目: { Name = "...", Value = ". .." }

源数组不仅可以包含 A 和 B 元素。例如,如果我们添加项目 { Name = "C", Value = "5" } 输出结果项目应包含 3 个元素,例如 {A1, B3, C5}

谢谢。

I need an LINQ query to get all combinations (distinct by name) for the following structure:

var keys = new[]
{
    new { Name = "A", Value = "1" },
    new { Name = "A", Value = "2" },
    new { Name = "B", Value = "3" },
    new { Name = "B", Value = "4" },
    // etc
};

I need to get:

{A1, B3} {A1, B4} {A2, B3} {A2, B4} // etc

where by A1-B4 I mean whole item: { Name = "...", Value = "..." }

Source array can contains not only A and B elements. For example if we add item { Name = "C", Value = "5" } output result items should contain 3 elements like {A1, B3, C5}.

Thank you.

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

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

发布评论

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

评论(4

无妨# 2024-11-13 14:42:06

该问题有多个步骤:

  1. 按“名称”将列表分成列表列表 L
  2. 执行列表 LxL 的笛卡尔积,其中列表是不同的
  3. 执行每对列表的笛卡尔积
  4. 合并所有结果。

这是一个实现:

var NameLists = keys.GroupBy(k => k.Name);

var NameListPairs = from first in NameLists
                    from second in NameLists where first != second
                    select new {first, second};

var Result = from pair in NameListPairs
             from first in pair.first
             from second in pair.second
             select new {first, second};

现在您已经完成了。请注意如何进行笛卡尔积的一般模式,其中我们同时从两个枚举中进行选择。

编辑:

如果您想要做的是所有名称列表上的笛卡尔积,请使用 此片段来自埃里克·利珀特。一旦你有了这个,你就可以像这样使用它:

var Result = keys.GroupBy(k => k.Name).CartesianProduct();

This problem has multiple steps:

  1. Separate a list by "Name" into a list of lists L
  2. Perform a cartesian product of list LxL where the lists are distinct
  3. Perfrom a cartesian product of each pair of lists
  4. Merge all the results.

And here is an implementation:

var NameLists = keys.GroupBy(k => k.Name);

var NameListPairs = from first in NameLists
                    from second in NameLists where first != second
                    select new {first, second};

var Result = from pair in NameListPairs
             from first in pair.first
             from second in pair.second
             select new {first, second};

And there you have it. Notice the general pattern of how to do a cartesian product, where we select form two enumerations at once.

EDIT:

If what you want to do is a cartesian product on all name lists, then use this snippet from Eric Lippert. Once you have this, you can use it like so:

var Result = keys.GroupBy(k => k.Name).CartesianProduct();
待天淡蓝洁白时 2024-11-13 14:42:06

尝试这样的事情:

var combinations = from A in keys.Where(k=>k.Name == "A")
                   from B in keys.Where(k=>k.Name == "B")
                   select new {A,B};

Try something like this:

var combinations = from A in keys.Where(k=>k.Name == "A")
                   from B in keys.Where(k=>k.Name == "B")
                   select new {A,B};
夜雨飘雪 2024-11-13 14:42:06

如果您想使用 Linq,请查看 Join 运算符并在其中破解您自己的比较器。

在此比较器中,您可以匹配键和值不同的项目。

        //
    // Summary:
    //     Correlates the elements of two sequences based on matching keys. A specified
    //     System.Collections.Generic.IEqualityComparer<T> is used to compare keys.
    //
    // Parameters:
    //   outer:
    //     The first sequence to join.
    //
    //   inner:
    //     The sequence to join to the first sequence.
    //
    //   outerKeySelector:
    //     A function to extract the join key from each element of the first sequence.
    //
    //   innerKeySelector:
    //     A function to extract the join key from each element of the second sequence.
    //
    //   resultSelector:
    //     A function to create a result element from two matching elements.
    //
    //   comparer:
    //     An System.Collections.Generic.IEqualityComparer<T> to hash and compare keys.
    //
    // Type parameters:
    //   TOuter:
    //     The type of the elements of the first sequence.
    //
    //   TInner:
    //     The type of the elements of the second sequence.
    //
    //   TKey:
    //     The type of the keys returned by the key selector functions.
    //
    //   TResult:
    //     The type of the result elements.
    //
    // Returns:
    //     An System.Collections.Generic.IEnumerable<T> that has elements of type TResult
    //     that are obtained by performing an inner join on two sequences.
    //
    // Exceptions:
    //   System.ArgumentNullException:
    //     outer or inner or outerKeySelector or innerKeySelector or resultSelector
    //     is null.
    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer);

If you wanna use Linq, then look at the Join operator and hack your own comparer in it.

Within this comparer, you can match items where both the Key and Value are different.

        //
    // Summary:
    //     Correlates the elements of two sequences based on matching keys. A specified
    //     System.Collections.Generic.IEqualityComparer<T> is used to compare keys.
    //
    // Parameters:
    //   outer:
    //     The first sequence to join.
    //
    //   inner:
    //     The sequence to join to the first sequence.
    //
    //   outerKeySelector:
    //     A function to extract the join key from each element of the first sequence.
    //
    //   innerKeySelector:
    //     A function to extract the join key from each element of the second sequence.
    //
    //   resultSelector:
    //     A function to create a result element from two matching elements.
    //
    //   comparer:
    //     An System.Collections.Generic.IEqualityComparer<T> to hash and compare keys.
    //
    // Type parameters:
    //   TOuter:
    //     The type of the elements of the first sequence.
    //
    //   TInner:
    //     The type of the elements of the second sequence.
    //
    //   TKey:
    //     The type of the keys returned by the key selector functions.
    //
    //   TResult:
    //     The type of the result elements.
    //
    // Returns:
    //     An System.Collections.Generic.IEnumerable<T> that has elements of type TResult
    //     that are obtained by performing an inner join on two sequences.
    //
    // Exceptions:
    //   System.ArgumentNullException:
    //     outer or inner or outerKeySelector or innerKeySelector or resultSelector
    //     is null.
    public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer);
白日梦 2024-11-13 14:42:06

这将得到所有组合,包括 {B3, A1} 等。

var cobinations = from a in keys
              from b in keys.Where(k => k.Name != a.Name)
              select new{ a, b };

This will get all combinations including {B3, A1}, etc.

var cobinations = from a in keys
              from b in keys.Where(k => k.Name != a.Name)
              select new{ a, b };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文