比较两个列表的Linq语法
本文关键字:列表 Linq 语法 两个 比较 | 更新日期: 2023-09-27 18:02:26
我有两个自定义类型对象列表
List<Obj> list1;
List<Obj> list2;
class Obj
{
public List<X> xlist;
public List<Y> Ylist;
public bool mybool;
}
class X
{
int x;
float y;
}
class Y
{
sting str;
bool y;
}
我想比较list1和list2中的每个成员是否具有相等的值。
您必须有意义地覆盖Equals
和GetHashCode
。您还可以为LINQ方法(如SequenceEqual
或Except
)实现IEquatable<Obj>
或使用自定义IEqualityComparer<Obj>
。例如:
public class Obj: IEquatable<Obj>
{
public List<X> xlist;
public List<Y> Ylist;
public bool mybool;
public bool Equals(Obj other)
{
if (other == null) return false;
if(object.ReferenceEquals(this, other)) return true;
if (mybool != other.mybool) return false;
return xlist.SequenceEqual(other.xlist) && Ylist.SequenceEqual(other.Ylist);
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = mybool ? 13 : 19;
foreach (X x in xlist)
{
hash = hash * 31 + x.GetHashCode();
}
foreach (Y y in Ylist)
{
hash = hash * 31 + y.GetHashCode();
}
return hash;
}
}
}
public class X: IEquatable<X>
{
public int x;
public float y;
public bool Equals(X other)
{
if (other == null) return false;
if (object.ReferenceEquals(this, other)) return true;
return x == other.x && y == other.y;
}
public override bool Equals(object obj)
{
var other = obj as X;
if (other == null) return false;
return this.Equals(other);
}
public override int GetHashCode()
{
unchecked
{
int hash = 19;
hash = hash * 31 + x;
hash = hash * 31 + (int)y;
return hash;
}
}
}
public class Y : IEquatable<Y>
{
public string str;
public bool y;
public bool Equals(Y other)
{
if (other == null) return false;
if (object.ReferenceEquals(this, other)) return true;
return str == other.str && y == other.y;
}
public override bool Equals(object obj)
{
var other = obj as Y;
if (other == null) return false;
return this.Equals(other);
}
public override int GetHashCode()
{
unchecked
{
int hash = 19;
hash = hash * 31 + (str == null ? 0 : str.GetHashCode());
hash = hash * 31 + (y ? 1 : 0);
return hash;
}
}
}
现在你可以用SequenceEqual
代替List<Obj>
:
bool sameItemsSameOrder = list1.SequenceEqual(list2); // finally you got your one-liner
有扩展方法SequenceEqual
。"通过使用默认的类型相等比较器比较元素来确定两个序列是否相等",并使用带有自己的相等比较器的重载。
var areEqual = list1.SequenceEqual(list2);
默认情况下,它调用列表中对象的Equals方法,因此请确保它按照您的需要执行或传递您自己的相等比较器。
Linq是一个查询语法。例如,你需要Linq在一个列表中查找不在另一个列表中的项。比较序列与SequenceEqual不是一个查询和IMHO不是真正的Linq。然而,这有关系吗?