Reputation: 149
I have:
List<INFRAESTRUCTURA> l1 = listQ1.ToList();
List<INFRAESTRUCTURA> l2 = listQ2.ToList();
And I need to intersect it comparing ids. Something like that:
l1.Intersect(l2, l1[].id_infraestructura == l2[].id_infraestructura)
But I don't know which method I must use and it sintax.
I found this:
var ids = list1.Select(a => a.id).Intersect(list2.Select(b => b.id));
But this return a list of ids and i need a list of elements contained in both lists.
Thank you!
Upvotes: 2
Views: 1739
Reputation: 26635
The other answers are correct, but you can use Intersect
with your custom comparer. You can create custom comparer by implementing IEqualityComparer<>
interface. And for implementing this interface we must implmenet two methods, Equals
and GetHashCode
.
public class InfraestructuraComparer: IEqualityComparer<INFRAESTRUCTURA>
{
/// <summary>
/// Whether the two INFRAESTRUCTURA are equal.
/// </summary>
public bool Equals(INFRAESTRUCTURA firstObj, INFRAESTRUCTURA secondObj)
{
if (firstObj == null && secondObj == null)
return true;
if (firstObj == null || secondObj == null)
return false;
// Your equality logic goes to here
return firstObj.ID == secondObj.ID;
}
/// <summary>
/// Return the hash code for this instance.
/// </summary>
public int GetHashCode(INFRAESTRUCTURA obj)
{
// Don't compute hash code on null object.
if (obj == null) return 0;
unchecked
{
var hash = 17;
hash = hash * 23 + obj.Id.GetHashCode();
return hash;
}
}
}
And then:
var result = list1.Intersect(list2, new InfraestructuraComparer());
You can also use this comparer in Except
method, for finding the difference of two sequences.
var result = list1.Except(list2, new InfraestructuraComparer());
Additionally:
From the first point of view you may misunderstood GetHashCode()
. You can read about this method in many question of StackOverflow. You can read the answer to this question.
Upvotes: 1
Reputation: 460068
I would use Enumerable.Join
:
var intersecting = from i1 in l1
join i2 in l2
on i1.id_infraestructura equals i2.id_infraestructura
select i1;
List<INFRAESTRUCTURA> result = intersecting.ToList();
If you would override Equals
+ GetHashCode
in INFRAESTRUCTURA
or provide a custom IEqualityComparer<INFRAESTRUCTURA>
you could use Enumerable.Intersect
directly:
List<INFRAESTRUCTURA> result = l1.Intersect(l2).ToList();
Here's a possible implementation:
public class InfrastructureComparer : IEqualityComparer<INFRAESTRUCTURA>
{
public bool Equals(INFRAESTRUCTURA x, INFRAESTRUCTURA y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
return x.id_infraestructura == y.id_infraestructura;
}
public int GetHashCode(INFRAESTRUCTURA obj)
{
if (obj == null) return 0;
return obj.id_infraestructura;
}
}
you can use the overloads which take an IEqualityComparer<T>
like here:
List<INFRAESTRUCTURA> result = l1.Intersect(l2, new InfrastructureComparer()).ToList();
If you want both objects in the result you could use an anonymous type:
var intersecting = from i1 in l1
join i2 in l2
on i1.id_infraestructura equals i2.id_infraestructura
select new { i1, i2 };
Upvotes: 2
Reputation: 5720
You can use Linq Join
l1.Join(l2, l => l.id_infraestructura, r => r.id_infraestructura, (l,r) => l.id_infraestructura);
Upvotes: 1