2013-10-28 20 views
0

上發現價值。如果我有數組:合併多個名單,但只保留全部名單

var list1 = new int[] { 1,2,3,4,5}; 
var list2 = new int[] { 1,2,3}; 
var list3 = new int[] { 2,3}; 

什麼方法可以幫我只能在所有列表中發現價值。在這個例子中,我想最終得到{2,3},因爲在所有列表中都可以找到這兩個值。

回答

3

您可以使用此方法來得到任何數量的序列的交集:

public static IEnumerable<T> IntersectAll<T>(params IEnumerable<T>[] sequences) 
{ 
    if (!sequences.Any()) 
     return Enumerable.Empty<T>(); 

    var set = new HashSet<T>(sequences.First()); 
    foreach (var sequence in sequences.Skip(1)) 
    { 
     set.IntersectWith(sequence); 
    } 
    return set; 
} 

注意,不同於重複調用LINQ Intersect方法,這會不會是反覆重建中間HashSet。它會重複使用同一個。

+0

不錯的解決方案!儘管我不確定hashset是否沒有特定的順序並且不允許重複,這是否重要? –

4

使用Intersect - >通過使用默認的相等比較器來比較值,生成兩個序列的集交集。 (MSDN:http://msdn.microsoft.com/en-us/library/bb460136.aspx

var list = list1.Intersect(list2).Intersect(list3); 
+0

將返回'{1,2,3,4,5}'我只想{ 2,3},因爲這些都是包含在所有列表中的唯一兩項。 –

+1

@TonoNam:不;這將返回你正在尋找的東西。 (測試) – SLaks

+0

哦,我用聯盟而不是Intersect這個詞來處理你的例子。感謝您的幫助,它效果很好! –

1

您可以使用相交方法是這樣的LINQ的一部分:

var result = list1.Intersect(list2).Intersect(list3); 

如果你想,你可以傳給你可以使用列表中的任意數量的方法這樣的:

public static int[] Process(params int[][] values) 
{ 
    int[] result = values[0]; 

    foreach (int[] value in values) 
    { 
     result = result.Intersect(value).ToArray(); 
    } 

    return result; 
} 

你可以這樣調用:

var result = Process(list1, list2, list3); 
+0

謝謝偉大的工程! –

+0

您的變量方法效率非常低,因爲您不僅不斷地不必要地將子交叉落實到數組中,而且不能在交集之間使用相同的中間「HashSet」。 – Servy

0

其他已經提出的良好和工作解決方案。根據他們的回答我提出這一個:

public static class IEnumerableExtension 
    { 
     public static IEnumerable<T> Intersect<T>(this IEnumerable<T> one, params IEnumerable<T>[] others) 
     { 
      var result = one; 
      foreach (var other in others) 
       result = result.Intersect(other); 

      return result; 
     } 
    } 

和使用將是這樣的:

var result = list1.Intersect(list2,list3,...continued to...listn);