在列表之间获取新项目和现有项目

时间:2016-10-12 12:42:53

标签: c# linq lambda

首先,我们引入新警报并反序列化它们。现在我只关心需要比较的2个属性:CommandID和AlertID,所有其他属性都可以忽略,所以我创建了一个新对象,我认为这个对象更容易比较结果。所有其他属性都为空。

List<AlertModel> alerts = JsonConvert.DeserializeObject<List<AlertModel>>(json)
.Select(x => new AlertModel() { CommandID = x.CommandID, AlertID = x.AlertID }).ToList();

现在我想找到尚未存在的新警报

List<AlertModel> newAlerts = alerts.Except(currentAlerts).ToList();

接下来,我们提取已存在的警报。

List<AlertModel> existingAlerts = currentAlerts.Intersect(alerts).ToList();

现在我们存储新的和现有的警报。

currentAlerts.Clear();
currentAlerts.AddRange(newAlerts);
currentAlerts.AddRange(existingAlerts);

第一轮alerts包含1项newAlerts包含1项,existingAlerts包含0项。

第二次跑步并不是我所期待的。

alerts包含1个应有的内容。

newAlerts包含1,此值应为0. currentAlerts包含与alerts中完全相同的CommandID和AlertID

existingAlerts包含0,因为currentAlertsalerts中存在相同的CommandID和AlertID,所以该值应为1。

不确定我在这里缺少什么,也许有更好的方法来做到这一点。

3 个答案:

答案 0 :(得分:1)

在AlertModel类中覆盖Equals和GetHashCode。如果要强制调用Equals方法,请在GetHashCode()中返回一个常量值(例如-1)。

public override bool Equals(object obj)
{
    var that = obj as AlertModel;

    return that != null && that.AlertId == this.AlertId && that.CommandId == this.CommandId; 
}

public override int GetHashCode()
    {           
        int hash = 13;
        return (this.AlertId.GetHashCode() * this.CommandID.GetHashCode()) ^ hash;
    }

答案 1 :(得分:1)

替换此代码:

List<AlertModel> newAlerts = alerts.Except(currentAlerts).ToList();

惠特:

List<AlertModel> newAlerts = alerts.Where(x => !currentAlerts.Any(y => y.CommandID == x.CommandID && y.AlertID == x.AlertID)).ToList();

问题是您的alerts列表包含新元素(new AlertModel() { CommandID = x.CommandID, AlertID = x.AlertID })。这是一个参考问题。

Animal a = new Animal { Color = "Red" };
Animal b = new Animal { Color = "Red" };
a == b; // This returns false

或者,您可以在班级中覆盖Equals方法。要在班上做到这一点:

public class AlertModel {
    // Some things

    public override bool Equals(object model) {
        return model != null && CommandID == model.CommandId && AlertID == model.AlertID;
    }
}

答案 2 :(得分:0)

var uniqueAlerts = alerts.Where(a=> !currentAlerts.Any(c=> c.CommandID == a.CommandID && c.AlertID== a.AlertID));