我有两个通用列表:
List<string> TestList1 = new List<string>();
List<string> TestList2 = new List<string>();
TestList1.Add("1");
TestList1.Add("2");
TestList1.Add("3");
TestList2.Add("3");
TestList2.Add("4");
TestList2.Add("5");
在这些列表中查找常用项目的最快方法是什么?
答案 0 :(得分:49)
假设您使用具有LINQ的.Net版本,则可以使用Intersect扩展方法:
var CommonList = TestList1.Intersect(TestList2)
答案 1 :(得分:8)
如果您有对象列表并想要获取某些属性的公共对象,请使用;
var commons = TestList1.Select(s1 => s1.SomeProperty).ToList().Intersect(TestList2.Select(s2 => s2.SomeProperty).ToList()).ToList();
注意: SomeProperty 是指您要实施的一些标准。
答案 2 :(得分:2)
假设你有LINQ可用。我不知道它是否是最快的,但干净的方式是这样的: <击> 撞击>
<击>var distinctStrings = TestList1.Union(TestList2).Distinct();
击> <击> 撞击>
var distinctStrings = TestList1.Union(TestList2);
更新:我不记得我的回答,我刚刚了解了Intersect!
根据评论中的更新,工会应用了一个独特的,现在我考虑它是有道理的。
答案 3 :(得分:1)
使用Intersect
方法:
IEnumerable<string> result = TestList1.Intersect(TestList2);
答案 4 :(得分:1)
对两个数组进行排序,从两者的顶部开始,并比较它们是否相等。
使用哈希更快:将第一个数组放入哈希值,然后比较第二个数组中的每个项目(如果它已经在哈希值中)。
我不知道那些Intersect和Union已经实现了。如果你关心性能,试着找出他们的运行时间。当然,如果您需要干净的代码,它们更适合。
答案 5 :(得分:1)
您可以通过计算所有列表中所有项目的出现次数来实现此目的 - 那些出现次数等于列表数量的项目对所有列表都是通用的:
static List<T> FindCommon<T>(IEnumerable<List<T>> lists)
{
Dictionary<T, int> map = new Dictionary<T, int>();
int listCount = 0; // number of lists
foreach (IEnumerable<T> list in lists)
{
listCount++;
foreach (T item in list)
{
// Item encountered, increment count
int currCount;
if (!map.TryGetValue(item, out currCount))
currCount = 0;
currCount++;
map[item] = currCount;
}
}
List<T> result= new List<T>();
foreach (KeyValuePair<T,int> kvp in map)
{
// Items whose occurrence count is equal to the number of lists are common to all the lists
if (kvp.Value == listCount)
result.Add(kvp.Key);
}
return result;
}
答案 6 :(得分:1)
使用HashSet进行快速查找。这是解决方案:
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<int> list1 = new List<int> {1, 2, 3, 4, 5, 6 };
List<int> list2 = new List<int> {1, 2, 3 };
List<int> list3 = new List<int> {1, 2 };
var lists = new IEnumerable<int>[] {list1, list2, list3 };
var commons = GetCommonItems(lists);
Console.WriteLine("Common integers:");
foreach (var c in commons)
Console.WriteLine(c);
}
static IEnumerable<T> GetCommonItems<T>(IEnumerable<T>[] lists)
{
HashSet<T> hs = new HashSet<T>(lists.First());
for (int i = 1; i < lists.Length; i++)
hs.IntersectWith(lists[i]);
return hs;
}
}
答案 7 :(得分:0)
按照@logicnp的顺序计算包含每个成员的列表数,一旦有了列表,就差不多是一行代码:
List<int> l1, l2, l3, cmn;
List<List<int>> all;
l1 = new List<int>() { 1, 2, 3, 4, 5 };
l2 = new List<int>() { 1, 2, 3, 4 };
l3 = new List<int>() { 1, 2, 3 };
all = new List<List<int>>() { l1, l2, l3 };
cmn = all.SelectMany(x => x).Distinct()
.Where(x => all .Select(y => (y.Contains(x) ? 1 : 0))
.Sum() == all.Count).ToList();
或者,如果您愿意:
public static List<T> FindCommon<T>(IEnumerable<List<T>> Lists)
{
return Lists.SelectMany(x => x).Distinct()
.Where(x => Lists.Select(y => (y.Contains(x) ? 1 : 0))
.Sum() == Lists.Count()).ToList();
}