-1

What is the syntax for finding a list of numbers both present in two or more List? I was looping through when I only needed to check two lists, but now I need to do several... Something like

List<int> commonIds = SELECT id from list1 
                     where list1.contains(id), 
                           list2.contains(id), 
                           list3.contains(id) ... 
Panagiotis Kanavos
  • 90,087
  • 9
  • 138
  • 171
Patrick Schomburg
  • 2,288
  • 1
  • 12
  • 35

4 Answers4

3

Finding the intersection of any number of lists

If you want to find the set of numbers that exist in all of the lists then Enumerable.Intersect is a good way to do so. You don't even have to hardcode the collection of lists, it can be created at runtime:

var lists = new[] { list1, list2, ..., listN }; // dynamically specified

var common = lists.First().AsEnumerable();
foreach (var list in lists.Skip(1))
{
    common = common.Intersect(list);
}

// and now common has the result, e.g.
var listOfCommonEntries = common.ToList();

Finding the union of intersections between master list and each other one

If you want to find the set which includes all common numbers between list 1 and list 2, union all common numbers between list 1 and list N, then it's somewhat different:

var common = Enumerable.Empty<int>();
foreach (var list in lists.Skip(1))
{
    common = common.Union(lists.First().Intersect(list));
}
Jon
  • 396,160
  • 71
  • 697
  • 768
  • don't you need the union of all the intersects of 2 combinations? – Jodrell May 07 '15 at 13:36
  • @Jodrell: Good question. Initially I thought not (also, you probably mean "pairs of the first list with each of the others"?), now I'm not so sure. – Jon May 07 '15 at 13:38
2

You can use Enumerable.Intersect:

List<int> commonIds = list1.Intersect(list2.Intersect(list3)).ToList();

It's pretty efficient since it's using a set.

Tim Schmelter
  • 411,418
  • 61
  • 614
  • 859
  • 1
    Why not chain the `Intersect` calls? ie `Intersect(list2).Intersect(list3)` – Panagiotis Kanavos May 07 '15 at 13:35
  • don't you need the union of all the intersects of 2 combinations? – Jodrell May 07 '15 at 13:36
  • @PanagiotisKanavos: works also, it was just the first that came to my mind. Maybe my nested approach is more efficient but i doubt it. – Tim Schmelter May 07 '15 at 13:44
  • @TimSchmelter Jodrell was asking about an alternative interpretation of the question. If this was your interpretation, you really should be searching for and closing as a duplicate :p – Rawling May 07 '15 at 13:45
  • @Rawling: Yes, my interpretation was this because OP's pseudo code was rather clear. And no, i don't have always the time to search duplicates, OP should do that before asking. – Tim Schmelter May 07 '15 at 13:49
  • I guess that's one way to get to 6-figure rep... "I don't have time to search for duplicates but I *do* have time to answer them" – Rawling May 07 '15 at 13:50
  • @Rawling: If you are already quoting me, please don't drop relevant parts. I have said that i have **not always** the time to find the duplicates. As you can [see easily](http://stackoverflow.com/users/284240/tim-schmelter?tab=votes&sort=closure) _sometimes_ i have the time. If a question seems rather clear and i know the answer, i will answer. If i have also the time to search if there is a duplicate i vote to close for duplicate, either before or after i've answered. – Tim Schmelter May 07 '15 at 13:59
1

Here is a function,

it returns the union of the intersect of all 2 set combinations.

public static IEnumerable<T> SharedItems<T>(this IEnumerable<IEnumerable<T>> source)
{
    var pairs =
            from s1 in source
            from s2 in source
            select new { s1 , s2 };

    var intersects = pairs
        .Where(p => p.s1 != p.s2)
        .Select(p => p.s1.Intersect(p.s2));

    return intersects.SelectMany(i => i).Distinct();
}
Jodrell
  • 31,518
  • 3
  • 75
  • 114
-1

to customize

void Main()
{
     List<int> one = new List<int>() {1, 3, 4, 6, 7};
     List<int> second = new List<int>() {1, 2, 4, 5};

     foreach(int r in one.Intersect(second))
        Console.WriteLine(r);
}
VISHMAY
  • 559
  • 4
  • 19