1

I have a list of objects X (with the name x) with properties a and b of the same type Location. I also have a list of locations y. I need to find all objects in x for which a AND b are contained in the list y.

I can do it with loops and Wheres but as both lists are huge, I need a really good performing solution. Is there any way to use Intersect in this case? Or something else?

Here some pseudo code

class X
{
    Location a;
    Location b;
}

GetMatches(List<X> x, List<Location> y) { ?? }
Antiohia
  • 1,142
  • 13
  • 37
  • 2
    Can you use `HashSet` instead of `List` ? then the `Contains` method would run in `O(1)` – Mong Zhu May 15 '19 at 11:12
  • It would be awesome if you could provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/reprex) – Fabjan May 15 '19 at 11:38
  • 1
    @mong-zhu, thank you, I will try it. It should be possible... I haven't thought about it. – Antiohia May 15 '19 at 11:58
  • 2
    @Fabjan, that would make the quite simple question pretty long and unreadable and cost me a plenty of time. As I don't need an answer with working code but ideas what to use, I prefer to have a short readable question and not additional overhead for both, me and the readers. – Antiohia May 15 '19 at 11:58

1 Answers1

2

First convert the y list to a HashSet.

var yHashSet = y.ToHashSet();

Then getting the matches is fast and easy:

private static List<X> GetMatches(List<X> x, HashSet<Location> y)
{
    return x
        .Where(item => y.Contains(item.a) && y.Contains(item.b))
        .ToList();
}

Make it parallel to become even faster:

private static List<X> GetMatchesParallel(List<X> x, HashSet<Location> y)
{
    return x
        .AsParallel()
        .AsOrdered()
        .Where(item => y.Contains(item.a) && y.Contains(item.b))
        .ToList();
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104