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

时间:2011-05-12 16:20:15

标签: c# .net 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}

谢谢。

4 个答案:

答案 0 :(得分:0)

尝试这样的事情:

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

这将获得包括{B3,A1}等在内的所有组合

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

答案 3 :(得分:0)

此问题有多个步骤:

  1. 将“名称”列表分隔为列表L
  2. 执行列表LxL的笛卡尔积,其中列表是不同的
  3. Perfrom每对名单中的笛卡尔产品
  4. 合并所有结果。
  5. 这是一个实现:

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

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

    编辑:

    如果您要做的是所有名称列表上的笛卡尔积,请使用this snippet from Eric Lippert。一旦你有了这个,你就可以这样使用它:

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