逐项列表比较,用结果更新每个项目(没有第三个列表)

时间:2013-01-28 15:02:26

标签: linq list collections compare

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

被比较的对象具有构成键的多个属性,加上构成值的属性,最后是描述比较结果的枚举属性,例如{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时,网格行将根据比较结果枚举进行样式设置,因此用户可以轻松查看新数据集中的键,但旧数据库中没有,反之亦然,以及两个数据集中的键都是不同的价值。两个列表都显示在数据网格的UI中,行根据比较结果设置样式。

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

谢谢!

1 个答案:

答案 0 :(得分: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;
    }
}