Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ intersect, multiple lists, some empty

Tags:

c#

linq

I'm trying to find an intersect with LINQ.

Sample:

List<int> int1 = new List<int>() { 1,2 };
List<int> int2 = new List<int>();
List<int> int3 = new List<int>() { 1 };
List<int> int4 = new List<int>() { 1, 2 };
List<int> int5 = new List<int>() { 1 };

Want to return: 1 as it exists in all lists.. If I run:

var intResult= int1
            .Intersect(int2)
            .Intersect(int3)
            .Intersect(int4)
            .Intersect(int5).ToList();

It returns nothing as 1 obviously isn't in the int2 list. How do I get this to work regardless if one list is empty or not ?

Use the above example or:

List<int> int1 = new List<int>() { 1,2 };
List<int> int2 = new List<int>();
List<int> int3 = new List<int>();
List<int> int4 = new List<int>();
List<int> int5 = new List<int>();

How do I return 1 & 2 in this case.. I don't know ahead of time if the lists are populated...

like image 448
gavin stevens Avatar asked Jul 07 '10 03:07

gavin stevens


1 Answers

If you need it in a single step, the simplest solution is to filter out empty lists:

public static IEnumerable<T> IntersectNonEmpty<T>(this IEnumerable<IEnumerable<T>> lists)
{
    var nonEmptyLists = lists.Where(l => l.Any());
    return nonEmptyLists.Aggregate((l1, l2) => l1.Intersect(l2));
}

You can then use it on a collection of lists or other IEnumerables:

IEnumerable<int>[] lists = new[] { l1, l2, l3, l4, l5 };
var intersect = lists.IntersectNonEmpty();

You may prefer a regular static method:

public static IEnumerable<T> IntersectNonEmpty<T>(params IEnumerable<T>[] lists)
{
    return lists.IntersectNonEmpty();
}

var intersect = ListsExtensionMethods.IntersectNonEmpty(l1, l2, l3, l4, l5);
like image 68
Kobi Avatar answered Oct 22 '22 00:10

Kobi