0

So i'm trying to make it as simple as possible, but stuck with finding the difference between my two Lists which both contain a Class called "Element". Each "Element" has 3 Propertys - Path,Name,Size. Now i want to compare ListA with ListB if ListA has a Element with the property Name that ListB doesn't have.

I already tried it with:

List<Element> diffList = from first in ListA
    join second in ListB
    on first.Name equals second.Name
    select first;

which was quite weird since, ListA's Maximum count is at about 60.000 and the diffList had a count of 22 Million. Also i tried it with:

List<Element> diffList = ListA
    .Where(w => !ListB.Contains(w.Name))
    .ToList();

This wasn't even possible to compile.

Thanks in advance.

Chookees
  • 33
  • 1
  • 7
  • MoreLinq's `ExceptBy`. – mjwills Mar 15 '19 at 08:34
  • "Lists which both contain a Class called "Element". Each "Element" has 3 Propertys - Path,Name,Size." "... if ListA has a Element with the property Name that ListB doesn't have." Isn't that a contradiction? – Grimm Mar 15 '19 at 08:35
  • @mjwills How can i use it? I've added the NuGet Package already. Would it be like "diffList = ListA.MoreLinq.SequenceException... " or how? – Chookees Mar 15 '19 at 08:38
  • Use the `Except` overload that expects an `EqualityComparer`, in which you can compare the property `Name` of your `Element` class: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except – IPValverde Mar 15 '19 at 08:39
  • @Grimm May i can not explain myself understandable enough, i'm not a native english speaker. I'll try it with a Backup example, assuming ListA is filled from the Source Directory and ListB is filled by the Destination. So if ListA has a new File it will be larger than ListB, and in this case i want to know which "Element" is different or missing in ListB, hope this is understandable. – Chookees Mar 15 '19 at 08:42
  • @Chookees Neither am I - no problem :-) Now I understand that it's about the value of the property, not the property itself. So reckface posted a good answer to this. – Grimm Mar 15 '19 at 08:46

1 Answers1

1

You want Any(), or All(), not Contains()

var diff= ListA.Where(e1 => !ListB.Any(e2=> e2.Name.Equals(e1.Name))).ToList();
// or better
var diff= ListA.Select(e => e.Name).Except(ListB.Select(e => e.Name)).ToList();

This may not be the best way for very large collections, and if you can avoid it, keep your collections as IEnumerables until you need to project your results.

reckface
  • 5,678
  • 4
  • 36
  • 62
  • The problem with this is, that diff is in my case also a List and i need to get the element by the property Name. In your Code i would get the Name as string but not the whole Element where the Name property not exists in ListB but in ListA. – Chookees Mar 15 '19 at 08:54
  • 1
    @Chookees I see. In that case, the first option. – reckface Mar 15 '19 at 08:57