2011-05-12 55 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