Linq 逐项列表比较,用结果更新每个项目(无第三个列表)
到目前为止,我在比较对象列表的研究中发现的解决方案通常会生成一个新的对象列表,比如一个列表中存在的项目,而另一个列表中不存在这些项目。在我的例子中,我想比较两个列表以发现其键存在于一个列表中而不存在于另一个列表中的项(比较两种方式),并且对于在两个列表中找到的键,检查值是否相同或不同 正在比较的对象有多个组成键的属性,加上一个组成值的属性,最后还有一个描述比较结果的枚举属性,例如{Equal、NotEqual、NoMatch、NotYetCompared}。所以我的对象可能看起来像:Linq 逐项列表比较,用结果更新每个项目(无第三个列表),linq,list,collections,compare,Linq,List,Collections,Compare,到目前为止,我在比较对象列表的研究中发现的解决方案通常会生成一个新的对象列表,比如一个列表中存在的项目,而另一个列表中不存在这些项目。在我的例子中,我想比较两个列表以发现其键存在于一个列表中而不存在于另一个列表中的项(比较两种方式),并且对于在两个列表中找到的键,检查值是否相同或不同 正在比较的对象有多个组成键的属性,加上一个组成值的属性,最后还有一个描述比较结果的枚举属性,例如{Equal、NotEqual、NoMatch、NotYetCompared}。所以我的对象可能看起来像: class
class MyObject
{
//Key combination
string columnA;
string columnB;
decimal columnC;
//The Value
decimal columnD;
//Enum for comparison, used for styling the item (value hidden from UI)
//Alternatively...this could be a string type, holding the enum.ToString()
MyComparisonEnum result;
}
这些对象被收集到两个可观测集合
中进行比较。当绑定到UI时,网格行将基于caomparison结果枚举设置样式,因此用户可以很容易地看到新数据集中有哪些键,而旧数据集中没有,反之亦然,以及两个数据集中具有不同值的键。这两个列表都以数据网格的形式显示在UI中,行的样式基于比较结果
LINQ是否适合作为有效解决此问题的工具,或者我是否应该使用循环扫描列表并在找到密钥时中断,等等(类似的解决方案自然来自于我的程序编程背景)。。。还是其他方法
谢谢大家! 您可以使用和:
当您适当地覆盖Equals
和GetHashCode
时:
class MyObject
{
//Key combination
string columnA;
string columnB;
decimal columnC;
//The Value
decimal columnD;
//Enum for comparison, used for styling the item (value hidden from UI)
//Alternatively...this could be a string type, holding the enum.ToString()
MyComparisonEnum result;
public override bool Equals(object obj)
{
if (obj == null || !(obj is MyObject)) return false;
MyObject other = (MyObject)obj;
return columnA.Equals(other.columnA) && columnB.Equals(other.columnB) && columnC.Equals(other.columnC);
}
public override int GetHashCode()
{
int hash = 19;
hash = hash + (columnA ?? "").GetHashCode();
hash = hash + (columnB ?? "").GetHashCode();
hash = hash + columnC.GetHashCode();
return hash;
}
}
你好,蒂姆!谢谢你的建议。似乎我必须生成新的列表作为调用方法的结果,如
Except
和Intersect
。我希望简单地维护两个原始列表,只更新每个项目的结果
属性。这就是说,我会尝试一下,让你知道它是如何进行的。Danke…我刚刚尝试实现了“在列表1中,而不是在列表2中”的场景,我很高兴地发现,我可以(显然)尝试使用我的绑定observateCollection
并直接更新result属性。但是,如果在两个列表中都可以找到一个项目,则不会检测到该项目。我在Equals
方法的覆盖中放置了一个断点,以尝试调试,但它没有被命中。我支持这一事实是其他问题的证据。@FrancisKhoury:您必须在GetHashCode
中设置断点,因为首先使用断点来确定两个对象是否相等。如果两个对象返回相同的值,则将使用Equals
验证相等性。因此,GetHashCode
是预检查,因此应该始终有效地实现它。你用过我的代码吗?蒂姆,请不要理会我的评论,这是一个数据问题,我在得到结果时能够调试它。你的建议很有效,我很乐意把它作为一个很好的答案!谢谢你的时间;我希望我在这件事上做得足够好,有机会报答你的好意。
var diffValue = from o1 in list1
join o2 in list2
on new { o1.columnA, o1.columnB, o1.columnC } equals new { o2.columnA, o2.columnB, o2.columnC }
where o1.columnD != o2.columnD
select new { Object1 = o1, Object2 = o2 };
foreach (var diff in diffValue)
{
MyObject obj1 = diff.Object1;
MyObject obj2 = diff.Object2;
Console.WriteLine("Obj1-Value:{0} Obj2-Value:{1}", obj1.columnD, obj2.columnD);
}
class MyObject
{
//Key combination
string columnA;
string columnB;
decimal columnC;
//The Value
decimal columnD;
//Enum for comparison, used for styling the item (value hidden from UI)
//Alternatively...this could be a string type, holding the enum.ToString()
MyComparisonEnum result;
public override bool Equals(object obj)
{
if (obj == null || !(obj is MyObject)) return false;
MyObject other = (MyObject)obj;
return columnA.Equals(other.columnA) && columnB.Equals(other.columnB) && columnC.Equals(other.columnC);
}
public override int GetHashCode()
{
int hash = 19;
hash = hash + (columnA ?? "").GetHashCode();
hash = hash + (columnB ?? "").GetHashCode();
hash = hash + columnC.GetHashCode();
return hash;
}
}