Intersection of Multiple Lists with Ienumerable.Intersect()

Intersection of multiple lists with IEnumerable.Intersect()

How about:

var intersection = listOfLists
.Skip(1)
.Aggregate(
new HashSet<T>(listOfLists.First()),
(h, e) => { h.IntersectWith(e); return h; }
);

That way it's optimized by using the same HashSet throughout and still in a single statement. Just make sure that the listOfLists always contains at least one list.

The fastest and easiest way to intersect all lists from two different objects

Simplest solution I can think of is Cascading Intersection:

var result = Projects.Intersect(Schools)
.Intersect(Locations)
.In‌​tersect(Interests​)
.Intersect(Hobbies)
.ToList();

LINQ intersect, multiple lists of an object, some empty

To start with lets define an extension method that will perform an intersection, but ignoring any list that is empty.

public static class Ex
{
public static IEnumerable<T> IntersectIgnoreEmpty<T>(this IEnumerable<T> @this, IEnumerable<T> other, IEqualityComparer<T> comparer)
{
return other.Any() ? @this.Intersect(other, comparer) : @this;
}
}

Now we define an equality comparer for objA:

public class objAEqualityComparer : IEqualityComparer<objA>
{
public bool Equals(objA left, objA right)
{
return
left.foo1 == right.foo1
&& left.foo2 == right.foo2
&& left.foo3 == right.foo3;
}

public int GetHashCode(objA @this)
{
return
@this.foo1.GetHashCode()
^ @this.foo2.GetHashCode()
^ @this.foo3.GetHashCode();
}
}

Then we can run this code:

List<objA> name1 = new List<objA>()
{
new objA { foo1 = 1, foo2 = "bb", foo3 = true },
new objA { foo1 = 2, foo2 = "cc", foo3 = false },
};
List<objA> name2 = new List<objA>();
List<objA> name3 = new List<objA>() { new objA { foo1 = 1, foo2 = "bb", foo3 = true } };
List<objA> name4 = new List<objA>()
{
new objA { foo1 = 1, foo2 = "bb", foo3 = true },
new objA { foo1 = 2, foo2 = "cc", foo3 = false },
};
List<objA> name5 = new List<objA>() { new objA { foo1 = 1, foo2 = "bb", foo3 = true } };

objAEqualityComparer comparer = new objAEqualityComparer();

List<objA> result =
name1
.IntersectIgnoreEmpty(name2, comparer)
.IntersectIgnoreEmpty(name3, comparer)
.IntersectIgnoreEmpty(name4, comparer)
.IntersectIgnoreEmpty(name5, comparer)
.ToList();

The result we get is:

result

You could always override Equals and GetHashCode in objA, but that would require making objA read-only so as to not break the equality contract - making an IEqualityComparer<objA> is a better choice in this case as it allows objA to be read/write.

Find common items in multiple lists in C# linq

var data = new [] {
new List<int> {1, 2, 3, 4, 5},
new List<int> {6, 7, 8, 9, 1},
new List<int> {3, 6, 9, 2, 0, 1},
new List<int> {1, 2, 9, 0, 5},
new List<int> {1, 7, 8, 6, 5, 4},
new List<int> {1},
new List<int> {},
null
};

IEnumerable<int> temp = null;
foreach (var arr in data)
if (arr != null && arr.Count != 0)
temp = temp == null ? arr : arr.Intersect(temp);

How to intersect multiple IEnumerable?

You probably want to use Union instead of Intersect. Here's the difference, I think it's self explanatory:
Union, intersection, difference comparison.

How to intersect two different IEnumerable collections

The question doesn't really make sense - what would the result type be? Intersections have to be performed on two sequences of the same type. It sounds like you don't so much want an intersection between two sets, as a filter of the first sequence based on possible values of z2. For example:

HashSet<int> validZ2 = new HashSet<int>(listB.Select(x => x.j6));
var filtered = listA.Where(x => validZ2.Contains(x.z2));

Or possibly as Gabe suggests, you want a join. For example:

var query = from a in listA
join b in listB on a.z2 equals b.j6
select new { a, b };

That will give you all pairings of values from the two lists which match on z2/j6.

Intersecting any number of Lists

Pretty simple:

var intersection = List1.Intersect(List2).Intersect(List3);

Or if you want to easily support n number of lists:

var lists = new List<List<string>>();

lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test3" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test4" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test5" }));
lists.Add(new List<string>(new string[] { "Test1", "Test2", "Test6" }));

var aggregate = lists.Aggregate((x, y) => x.Intersect(y).ToList());


Related Topics



Leave a reply



Submit