上發現價值。如果我有數組:合併多個名單,但只保留全部名單
var list1 = new int[] { 1,2,3,4,5};
var list2 = new int[] { 1,2,3};
var list3 = new int[] { 2,3};
什麼方法可以幫我只能在所有列表中發現價值。在這個例子中,我想最終得到{2,3}
,因爲在所有列表中都可以找到這兩個值。
上發現價值。如果我有數組:合併多個名單,但只保留全部名單
var list1 = new int[] { 1,2,3,4,5};
var list2 = new int[] { 1,2,3};
var list3 = new int[] { 2,3};
什麼方法可以幫我只能在所有列表中發現價值。在這個例子中,我想最終得到{2,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
。它會重複使用同一個。
使用Intersect
- >通過使用默認的相等比較器來比較值,生成兩個序列的集交集。 (MSDN:http://msdn.microsoft.com/en-us/library/bb460136.aspx)
var list = list1.Intersect(list2).Intersect(list3);
將返回'{1,2,3,4,5}'我只想{ 2,3},因爲這些都是包含在所有列表中的唯一兩項。 –
@TonoNam:不;這將返回你正在尋找的東西。 (測試) – SLaks
哦,我用聯盟而不是Intersect這個詞來處理你的例子。感謝您的幫助,它效果很好! –
您可以使用相交方法是這樣的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);
謝謝偉大的工程! –
您的變量方法效率非常低,因爲您不僅不斷地不必要地將子交叉落實到數組中,而且不能在交集之間使用相同的中間「HashSet」。 – Servy
其他已經提出的良好和工作解決方案。根據他們的回答我提出這一個:
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);
不錯的解決方案!儘管我不確定hashset是否沒有特定的順序並且不允許重複,這是否重要? –