在 C# 中的 2 个集合之间相交
本文关键字:之间 集合 中的 | 更新日期: 2023-09-27 18:32:00
我有:
List<INFRAESTRUCTURA> l1 = listQ1.ToList();
List<INFRAESTRUCTURA> l2 = listQ2.ToList();
我需要与它相交比较 id。像这样:
l1.Intersect(l2, l1[].id_infraestructura == l2[].id_infraestructura)
但我不知道我必须使用哪种方法,它是罪恶的。
我发现这个:
var ids = list1.Select(a => a.id).Intersect(list2.Select(b => b.id));
但是这会返回一个 id 列表,我需要两个列表中包含的元素列表。
谢谢!
我会使用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();
如果要覆盖INFRAESTRUCTURA
中的 Equals
+ GetHashCode
或提供自定义IEqualityComparer<INFRAESTRUCTURA>
可以直接使用Enumerable.Intersect
:
List<INFRAESTRUCTURA> result = l1.Intersect(l2).ToList();
下面是一个可能的实现:
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;
}
}
您可以使用重载,如下所示IEqualityComparer<T>
:
List<INFRAESTRUCTURA> result = l1.Intersect(l2, new InfrastructureComparer()).ToList();
如果您希望结果中同时存在两个对象,则可以使用匿名类型:
var intersecting = from i1 in l1
join i2 in l2
on i1.id_infraestructura equals i2.id_infraestructura
select new { i1, i2 };
其他答案是正确的,但您可以将Intersect
与自定义比较器一起使用。您可以通过实现IEqualityComparer<>
接口创建自定义比较器。为了实现这个接口,我们必须输入两种方法, Equals
和 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;
}
}
}
然后:
var result = list1.Intersect(list2, new InfraestructuraComparer());
您也可以在Except
方法中使用此比较器来查找两个序列的差异。
var result = list1.Except(list2, new InfraestructuraComparer());
此外:
从第一个角度来看,您可能会误解GetHashCode()
.您可以在StackOverflow的许多问题中阅读此方法。您可以阅读此问题的答案。
您可以使用 Linq Join
l1.Join(l2, l => l.id_infraestructura, r => r.id_infraestructura, (l,r) => l.id_infraestructura);