首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Linq比较2个对象列表

Linq比较2个对象列表
EN

Stack Overflow用户
提问于 2016-06-14 09:35:14
回答 2查看 112关注 0票数 1

我知道类似的问题已经通过了这个董事会,但我找不到一个回答我的问题。

我有2个list<myObject>,有3个属性。

全班:

代码语言:javascript
运行
复制
    public int MeterID {get; set;}
    public string Datum { get; set; }
    public int NumberOfValues { get; set; }

    public myObject(int meterID, string datum, int numberOfValues)
    {
        this.ID= ID;
        this.Datum = datum;
        this.NumberOfValues = numberOfValues;
    }

我想根据以下两个值ID, Datum比较这些列表,但是我希望结果仍然是一个List<MyObject>,所以当我的对象在listA和listB中时,在执行下面的linq语句之后,它不应该出现在newList

代码语言:javascript
运行
复制
var newList = ListA.Select(x => new { x.ID, x.Datum }).Except(ListB.Select(z => new { z.ID, z.Datum }));

该语句没有为我提供一个MyObject列表,而是提供了一个只有ID和数据的列表。我还需要来自ListA的ListA属性在newList中。

有什么方法可以用linq实现这一点吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-14 09:38:26

我会这样做的:

代码语言:javascript
运行
复制
var result = ListA.Where(a => 
                ListB.All(b => b.ID != a.ID || b.Datum != a.Datum)).ToList();

这将获取ListA中的所有元素,对于这些元素,ListB中的所有元素都是不同的(对于不同的定义而言)。

如果您还想拥有不存在于ListB中的ListA元素,则可以组合结果:

代码语言:javascript
运行
复制
var result = ListA.Where(a => 
                ListB.All(b => b.ID != a.ID || b.Datum != a.Datum)).
                Concat(ListB.Where(b => 
                        ListA.All(a => b.ID != a.ID || b.Datum != a.Datum)).
             ToList();
票数 6
EN

Stack Overflow用户

发布于 2016-06-14 10:30:13

另一个选项是使用Enumerable.Except()IEqualityComparer一起从listB中排除这些项。

代码语言:javascript
运行
复制
public class MyObject
{
    public int MeterID { get; set; }
    public string Datum { get; set; }
    public int NumberOfValues { get; set; }

    public MyObject(int meterID, string datum, int numberOfValues)
    {
        this.MeterID = meterID;
        this.Datum = datum;
        this.NumberOfValues = numberOfValues;
    }
}

public class MyObjectEqualityComparer : EqualityComparer<MyObject>
{
    public override bool Equals(MyObject x, MyObject y)
    {
        return x.MeterID == y.MeterID
            && x.Datum == y.Datum;
    }

    public override int GetHashCode(MyObject obj)
    {
        return obj.MeterID ^ obj.Datum.GetHashCode();
    }
}

通过对外部对象中的比较标准进行编码,可以更容易地在其他地方重用它,并简化更改。

代码语言:javascript
运行
复制
[TestClass]
public class CompareListsFixture
{

    [TestMethod]
    public void CompareLists()
    {
        var listA = new List<MyObject>
        {
            new MyObject(1,"A", 5), // Matches with 1/A/1
            new MyObject(1,"B", 4),
            new MyObject(2,"A", 3), // Matches with 2/A/4
            new MyObject(2,"C", 2),
        };

        var listB = new List<MyObject>
        {
            new MyObject(1,"A", 1),
            new MyObject(2,"A", 4),
            new MyObject(3,"A", 8),
        };

        var expected = new List<MyObject>
        {
            new MyObject(1,"B", 4),
            new MyObject(2,"C", 2),
        };

        var actual = listA.Except(listB, new MyObjectEqualityComparer());

        CollectionAssert.AreEqual(expected, actual.ToList(), new MyObjectComparer());

    }

}

我们使用一个比较器来比较Collection.Assert()中的整个对象

代码语言:javascript
运行
复制
public class MyObjectComparer : Comparer<MyObject>
{
    public override int Compare(MyObject x, MyObject y)
    {
        return Format(x).CompareTo(Format(y));
    }

    private static string Format(MyObject obj)
    {
        return $"{obj.MeterID}:{obj.Datum}:{obj.NumberOfValues}";
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37808233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档