0

到目前为止,我在比较对象列表的研究中发现的解决方案通常会生成一个新的对象列表,比如那些存在于一个列表中但不存在于另一个列表中的项目。就我而言,我想比较两个列表以发现其键存在于一个列表中而不存在于另一个列表中的项目(比较两种方式),并且对于在两个列表中找到的那些键,检查值是相同还是不同。

被比较的对象有多个构成键的属性,加上一个构成值的属性,最后还有一个描述比较结果的枚举属性,例如,{Equal, NotEqual, NoMatch, NotYetCompared}。所以我的对象可能看起来像:

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

这些对象被收集成两个ObservableCollection<MyObject>进行比较。当绑定到 UI 时,网格行的样式基于 caomparison 结果枚举,因此用户可以很容易地看到新数据集中有哪些键,但旧数据集中没有,反之亦然,以及两个数据集中的键不同的价值。两个列表都以数据网格的形式呈现在 UI 中,行的样式基于比较结果。

LINQ 是否适合作为有效解决此问题的工具,或者我应该使用循环来扫描列表并在找到密钥时中断等等(这样的解决方案自然来自我的程序编程背景)......或其他方法?

谢谢!

4

1 回答 1

0

您可以使用ExceptIntersect

var list1 = new List<MyObject>();
var list2 = new List<MyObject>();
// initialization code 
var notIn2 = list1.Except(list2);
var notIn1 = list2.Except(list1);
var both = list1.Intersect(list2);

要查找具有不同值 ( ColumnD) 的对象,您可以使用这个(非常有效的)Linq 查询:

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

当您覆盖EqualsGetHashCode适当地:

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;
    }
}
于 2013-01-28T15:10:27.260 回答