How should I compare values in two lists?

前端 未结 4 753
臣服心动
臣服心动 2021-02-05 13:39

I have two lists

List 01 => { A, B, C, D, E }
List 02 => { F, F, F, F, E }

I need to check if one element of List 02 exists

相关标签:
4条回答
  • 2021-02-05 14:12

    try

    list1.Any(e => list2.Contains(e));
    

    e.g.

    var list1 = new List<string> { "A", "B", "C", "D" };
    var list2 = new List<string> { "F", "F", "F" };
    
    list1.Any(e => list2.Contains(e)); // returns false
    
    var list3 = new List<string> { "F", "F", "D" };
    
    list1.Any(e => list3.Contains(e)); // returns true
    

    UPDATE: as leppie points out, using Intersect will be more performant, esp if the lists are large.

    0 讨论(0)
  • 2021-02-05 14:30

    Enumerable.Except & Enumerable.Intersect.

    0 讨论(0)
  • 2021-02-05 14:31

    There are a few different ways to do it:

    Intersect

    If the result of the intersection result in 1 or more elements, it means that at least one equal element.

    var result = list01.Intersect(list02);
    bool hasElement = result.Any();
    

    I recommend the use of this method.

    It is possible to pass a IEqualityComparer<T> as the second parameter in case you need to compare complex types.

    Except

    If the result of a except has different amount of elements in total, it means that there is at least one equal element.

    var result = list01.Except(list02);
    bool hasElement = result.Count() != list01.Count;
    

    It is possible to pass a IEqualityComparer<T> as the second parameter in case you need to compare complex types.

    Any

    If any element in the list01 is equal any element in the list02, it means that there is at least one equal element.

    bool hasElement = list01.Any(e => list02.Any(o => o == e));
    

    Any e IndexOf

    If any element in the list01 is found in list02, it means that there is at lease one equal element.

    bool hasElement = list01.Any(e => list02.IndexOf(e) != -1);
    

    The disadvantage of IndexOf is that you can't pass a IEqualityComparer<T>, instead it will always use the default, EqualityComparer<T>.Default.


    Performance

    In a big list, list01.Any(e => list02.Any(o => o == e)) will have a good performance only if one of the values from the beginning of the first in contained in the second list. Otherwise the performance will be awful, as the iterations are sequential.

    In a performance test I got the following results:

    Lists with 5 elements each, tested 10000000 times.

    Intersect     : 00:00:02.9260135
    Except        : 00:00:03.4404527
    AnyAny        : 00:00:06.5709693
    AnyIndexOf    : 00:00:01.9882278
    

    Lists with 100000 elements each, tested 500 times. The last element of list02 is equal to the third element in list01:

    Intersect     : 00:00:02.4397784
    Except        : 00:00:04.2595364
    AnyAny        : 00:00:02.9761128
    AnyIndexOf    : 00:00:00.0919344
    

    Lists with 100000 elements each, tested 500 times. The last element of list02 is equal to the last element in 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
    
    0 讨论(0)
  • 2021-02-05 14:35
    list1.Intersect(list2).Any()
    

    This will be most performant as it uses HashSets.

    0 讨论(0)
提交回复
热议问题