在 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 列表,我需要两个列表中包含的元素列表。

谢谢!

在 C# 中的 2 个集合之间相交

我会使用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<>接口创建自定义比较器。为了实现这个接口,我们必须输入两种方法, EqualsGetHashCode .

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);