我有两个大的列表,list1有4列,list2有3列。 如果list1在列1和列3中包含与list2相同的值,那么我需要在list1中删除该项。我实际上正在寻找一些优势和有效的解决方案。谢谢你的帮助。
List1:
1, 5, 3, 9 // Remove this
11, 15, 18, 6 // Keep this
List2:
1, 5, 3
List<Tuple<int, int, int, int>> list1 = new List<Tuple<int, int, int, int>>();
List<Tuple<int, int, int>> list2 = new List<Tuple<int, int, int>>();
答案 0 :(得分:2)
理想情况下,从性能角度来看,您可以利用HashSet.SymmetricExceptWith
,但是您使用的是两种不同的类型(以及Tuples
)。
Except
是一种可能的解决方案:
list1 = list1.Except(list1
.Where(l1 => list2
.Any(l2 => l2.Item1 == l1.Item1
&& l2.Item2 == l1.Item2
&& l2.Item3 == l1.Item3)))
.ToList();
答案 1 :(得分:1)
var index2 = list2.ToLookup(t => Tuple.Create(t.Item1, t.Item3));
//var index2 = list2.Select(l => Tuple.Create(l.Item1, l.Item3)).ToList();
//index2.Sort();
var results = from l in list1
where !index2.Contains(Tuple.Create(l.Item1, l.Item3))
select l;
这可能相当有效。缺点是index2增加了内存使用量。注释掉了另一种索引方法,该方法在内存上稍微容易一些。 ToList版本不会存储对原始记录的引用,因此它会更轻量级。但ToLookup索引可能比这个特定问题有更多用途。 ToDictionary也可以是一个选项,而不是ToLookup,如果每个键都是唯一的,但这是重量级的倒退。
根据这些列表的确实大小,可以通过几个很好的AsParallel()调用获得额外的收益。
var index2 = list2.AsParallel().ToLookup(t => Tuple.Create(t.Item1, t.Item3));
var results = from l in list1.AsParallel()
where !index2.Contains(Tuple.Create(l.Item1, l.Item3))
select l;
尝试使用其中一个或两个,因为只有您的环境可以告诉我们这是否是最好的。有时,在多个线程上分配工作的费用可能比连续完成工作花费更长的时间。