如何使用 LINQ 获取按某些字段区分的组合



我需要 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} .

谢谢。

此问题有多个步骤:

  1. 按"名称"将列表分隔为列表列表 L
  2. 执行列表 LxL 的笛卡尔乘积,其中列表是不同的
  3. Perfrom 每对列表的笛卡尔乘积
  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};

你有它。 注意如何做笛卡尔积的一般模式,我们一次选择两个枚举。

编辑:

如果你想做的是所有名称列表中的笛卡尔产品,那么使用Eric Lippert的这个片段。 有了这个,你可以像这样使用它:

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

尝试这样的事情:

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

如果你想使用 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);

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

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

相关内容

  • 没有找到相关文章

最新更新