Trying to get distinct values from two List objects

后端 未结 6 853
Happy的楠姐
Happy的楠姐 2020-12-18 00:47

I have 2 List objects:

List lst1 = new List();
List lst2 = new List();

Let\'s say they have val

相关标签:
6条回答
  • 2020-12-18 01:21

    If the results are coming from database it would be better to process them there. It will be much faster compared to in memory operation especially if there are lots of results.

    If you have to process them in your code you can use i4o - Indexed LINQ to make it faster.

    0 讨论(0)
  • 2020-12-18 01:22

    In Linq:

    var distinct = lst2.Contact(lst1).Distinct().ToList();
    

    (Your explanation appears to say that you want the unique elements in both lists. But your example appears that you want the union of both lists).

    0 讨论(0)
  • 2020-12-18 01:23

    EDIT: thanks to the comments you need to do some extra work besides just using Except to get a symmetric difference. If an additional value is added to the 2nd list Except alone would be incorrect. To get the proper result try this:

    var list1 = new List<int>(Enumerable.Range(1,4));
    var list2 = new List<int> { 1, 4, 6 };
    
    var result = list1.Except(list2).Union(list2.Except(list1));
    

    The above returns {2, 3, 6}.

    Note that you'll need to add a ToList() if you really need a List<int>, otherwise the above operation will return an IEnumerable<int>.


    Use the Enumerable.Except method, which produces the set difference of two sequences:

    var result = lst1.Except(lst2);
    
    0 讨论(0)
  • 2020-12-18 01:24

    Ahmad is nearly right with Except, I believe - but that won't give you items which are in lst2 but not in lst1. So in the example you gave, if you added 5 to lst2, I imagine you'd want the result to be {2, 3, 5}. In that case, you want a symmetric difference. I don't think there's any way to do that directly in LINQ to Objects in a single call, but you can still achieve it. Here's a simple but inefficient way to do it:

    lst1.Union(lst2).Except(lst1.Intersect(lst2)).ToList();
    

    (Obviously you only need ToList() if you genuinely need a List<T> instead of an IEnumerable<T>.)

    The way to read this is "I want items that are in either list but not in both."

    It's possible that it would be more efficient to use Concat - which would still work as Except is a set based operator which will only return distinct results:

    lst1.Concat(lst2).Except(lst1.Intersect(lst2)).ToList();
    
    0 讨论(0)
  • 2020-12-18 01:33

    Just that -

    var distinct = a.Union(b);
    
    0 讨论(0)
  • 2020-12-18 01:34

    LINQ would be the easy way, grouping each item based on it's value and then selecting only the ones that have one element:

    from i in lst1.Concat(lst2)
    group i by i into g
    where !g.Skip(1).Any()
    select g.Key;
    

    Using Skip here will allow you to make sure that no more than one element exists; if there is 1 or less elements in the sequence, an empty sequence is returned, on which Any will return false.

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