2011-05-12 75 views
1

得到不同的组合,我需要一个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}

谢谢。

+2

为什么不使用嵌套for? – soandos 2011-05-12 16:21:57

+0

可能是..但我认为用LINQ解决方案应该更短,更优雅。 – Rizzo 2011-05-12 20:39:51

回答

0

这个问题有多个步骤:

  1. 单独列表的 “名称” 到一个列表列表L
  2. 执行列表LxL的笛卡尔产品,其中列表是不同的
  3. Perfrom a car每对清单的tesian产品
  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}; 

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

编辑:

如果你想要做的是所有名单笛卡尔积,然后用this snippet from Eric Lippert。一旦你有这个,你可以像这样使用它:

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

谢谢克里斯,但我想澄清一下。源数组不仅可以包含A和B元素。例如,如果我们添加项目{Name =“C”,Value =“4”}。输出结果项目应包含3个元素,如{A1,B3,C5}。 – Rizzo 2011-05-12 19:34:27

+0

感谢您的有用的文章! – Rizzo 2011-05-13 18:04:30

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

感谢KeithS,但我想澄清一下。源数组不仅可以包含A和B元素。例如,如果我们添加项目{Name =“C”,Value =“4”}。输出结果项目应包含3个元素,如{A1,B3,C5}。 – Rizzo 2011-05-12 19:34:52

+0

那么,您可以根据需要扩展此查询以获取任意数量的已知维度。对于一般情况,它变得更加困难。看我的编辑。 – KeithS 2011-05-13 14:23:06

0

如果你想使用Linq,再看看加入运营商和黑客自己的比较器在里面。

在此比较器中,您可以匹配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); 
0

这将让所有的组合包括{B3,A1}等

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

谢谢Pop,但我想澄清一下。源数组不仅可以包含A和B元素。例如,如果我们添加项目{Name =“C”,Value =“4”}。输出结果项目应包含3个元素,如{A1,B3,C5}。 – Rizzo 2011-05-12 19:34:02