我该如何比较两个列表中的值?

Bru*_*oLM 13 .net c# linq

我有两个清单

List 01 => { A, B, C, D, E }
List 02 => { F, F, F, F, E }
Run Code Online (Sandbox Code Playgroud)

我需要检查是否List 02存在一个元素List 01,所以以下内容应该是false.

List 01 => { A, B, C, D, E }
List 02 => { F, F, F, F, F } // no element matches
Run Code Online (Sandbox Code Playgroud)

这应该是true.

List 01 => { A, B, C, D, E }
List 02 => { F, F, F, F, B } // last element matches
Run Code Online (Sandbox Code Playgroud)

我该怎么检查?

我也很关心表现.

Tim*_*ers 13

list1.Intersect(list2).Any()
Run Code Online (Sandbox Code Playgroud)

这将是最高效的,因为它使用HashSet.


Bru*_*oLM 6

有几种不同的方法可以做到:

相交

如果交集的结果导致1个或多个元素,则表示至少有一个相等的元素.

var result = list01.Intersect(list02);
bool hasElement = result.Any();
Run Code Online (Sandbox Code Playgroud)

我建议使用这种方法.

IEqualityComparer<T>如果需要比较复杂类型,可以将a 作为第二个参数传递.

除了

如果一个except的结果总共有不同数量的元素,则意味着至少有一个相等的元素.

var result = list01.Except(list02);
bool hasElement = result.Count() != list01.Count;
Run Code Online (Sandbox Code Playgroud)

IEqualityComparer<T>如果需要比较复杂类型,可以将a 作为第二个参数传递.

任何

如果list01中的任何元素与list02中的任何元素相等,则表示至少有一个相等的元素.

bool hasElement = list01.Any(e => list02.Any(o => o == e));
Run Code Online (Sandbox Code Playgroud)

任何 e IndexOf

如果在list02中找到list01中的任何元素,则意味着至少有一个相等的元素.

bool hasElement = list01.Any(e => list02.IndexOf(e) != -1);
Run Code Online (Sandbox Code Playgroud)

缺点IndexOf是你不能传递IEqualityComparer<T>,而是总是使用默认值EqualityComparer<T>.Default.


性能

在一个大的列表中,只有在第二个列表中包含的第一个开头的值之一时才list01.Any(e => list02.Any(o => o == e))会有良好的性能.否则性能会很糟糕,因为迭代是连续的.

在性能测试中,我得到了以下结果:

每个列表包含5个元素,测试10000000次.

Intersect     : 00:00:02.9260135
Except        : 00:00:03.4404527
AnyAny        : 00:00:06.5709693
AnyIndexOf    : 00:00:01.9882278
Run Code Online (Sandbox Code Playgroud)

每个列有100000个元素,测试500次.list02的最后一个元素等于list01中的第三个元素:

Intersect     : 00:00:02.4397784
Except        : 00:00:04.2595364
AnyAny        : 00:00:02.9761128
AnyIndexOf    : 00:00:00.0919344
Run Code Online (Sandbox Code Playgroud)

每个列有100000个元素,测试500次.list02的最后一个元素等于list01中的最后一个元素.

Intersect     : 00:00:02.4927969
Except        : 00:00:04.2668677
AnyAny        : more than a minute and I dropped the test
AnyIndexOf    : more than a minute and I dropped the test
Run Code Online (Sandbox Code Playgroud)


lep*_*pie 5

Enumerable.Except&Enumerable.Intersect.