C# 比较两个列表中对象的属性
我有以下(简化)课程: 我只想比较两个C# 比较两个列表中对象的属性,c#,.net,linq,linq-to-entities,C#,.net,Linq,Linq To Entities,我有以下(简化)课程: 我只想比较两个CareRate列表的DayRate;一个带有CareRates的,包含当前DayRates的,一个带有CareRates的,包含要更新的DayRates。其他可能已更改的属性(如描述)不应考虑在内 // Just a test method public List<CareRate> FilterChangedCareRates(){ var currentCareRates = new List<CareRate>{
CareRate
列表的DayRate
;一个带有CareRates
的,包含当前DayRates
的,一个带有CareRates
的,包含要更新的DayRates
。其他可能已更改的属性(如描述)不应考虑在内
// Just a test method
public List<CareRate> FilterChangedCareRates(){
var currentCareRates = new List<CareRate>{
new CareRate { Id = 1, DayRate = 3,33, Description = "Some descr" },
new CareRate { Id = 2, DayRate = 4,44, Description = "Some other descr" }
};
var updatedCareRates = new List<CareRate>{
new CareRate { Id = 1, DayRate = 2,22 },
new CareRate {Id = 2, DayRate = 4,44 } // Unchanged
};
var actualUpdatedCareRates = new List<CareRate>();
foreach(var updatedCareRate in updatedCareRates) {
var currentCareRate = currentCareRates.Single(x => x.Id == updatedCareRate.Id);
if (updatedCareRate.DayRate != currentCareRate.DayRate) {
actualUpdatedCareRates.Add(updatedCareRate);
}
}
return actualUpdatedCareRates;
}
//只是一种测试方法
公共列表筛选器更改费率(){
var currentCareRates=新列表{
新的CareRate{Id=1,DayRate=3,33,Description=“Some descr”},
新的CareRate{Id=2,DayRate=4,44,Description=“Some other descr”}
};
var updatedCareRates=新列表{
新的监护率{Id=1,DayRate=2,22},
新的监护率{Id=2,DayRate=4,44}//未改变
};
var actualUpdatedCareRates=新列表();
foreach(updatedCareRates中的var updatedCareRate){
var currentCareRate=currentCareRates.Single(x=>x.Id==updatedCareRate.Id);
if(updatedCareRate.DayRate!=currentCareRate.DayRate){
actualUpdatedCareRates.Add(updatedCareRate);
}
}
返回实际更新的利率;
}
按
Dayrate
过滤已更改的CareRate
对象的方式感觉有点迂回。我想我忽略了什么。有什么其他更好的选择可以获得上述信息?我认为,您可以使用以下内容:
updatedCareRates.ForEach(x =>
{
if (currentCareRates.FirstOrDefault(y => y.Id == x.Id && y.DayRate != x.DayRate) != null)
actualUpdatedCareRates.Add(x);
});
或者在一行中:
updatedCareRates.Where(x => currentCareRates.FirstOrDefault(y => y.Id == x.Id &&
y.DayRate != x.DayRate) != null).ToList()
.ForEach(x => actualUpdatedCareRates.Add(x));
在LINQ中简单使用方法:
var actualUpdatedCareRates = currentCareRates.Zip(updatedCareRates,
(f, s) => f.DayRate != s.DayRate ? s : null)
.Where(c => c != null).ToList();
您可以使用以下选项:
return (from up in updatedCareRates
join cur in currentCareRates
on up.Id equals cur.Id
where up.DayRate != cur.DayRate
select up).ToList();
这里是我认为查询语法优于方法语法的罕见案例之一。我没有使用
where(x=>x…)
,而是使用方法寻找解决方案,但发布的方法除外
我创建了一个类DayRateComparer
,如下所示
public class DayRateComparer : IEqualityComparer<CareRate>
{
public bool Equals(CareRate x, CareRate y) {
if (x = null) throw new ArgumentNullException(nameof(x));
if (y = null) throw new ArgumentNullException(nameof(y));
return x.Id == y.Id && x.DayRate == y.DayRate;
}
public int GetHashCode(CareRate obj) {
retun obj.Id.GetHashCode() + obj.DayRate.GetHashCode();
}
}
我不喜欢使用临时列表(如actualUpdatedCareRates
),在使用比较器时,这不再是必需的。所提到的Zip
方法也是一种简洁的方法,但乍一看有点复杂。谢谢大家的发帖。我不太确定你想用你提到的列表做什么。。您是在查看费率发生变化的项目列表,还是使用新费率更新了所有原始项目的列表?这似乎是一个回顾。可能应该转到CodeReview.change。com@BugFinder希望有一个只更改了DayRate(与当前DayRate相比)的CareRate的新列表。您可以在一行中执行此操作:return updatedCareRates.Where(updated=>currentCareRates.Any(current=>current.DayRate!=updated.DayRate))
@HimBromBeere Codereview.stackexchange.com,是的。那边最好是非简化版,请参考。NoZip
并不像你想象的那么复杂。去看看我在回答中提到的链接是如何工作的。它使您的工作比为此编写比较器容易得多,同时您可以轻松地使用Zip
方法IMO.@S.Akbari,您是对的。它没有那么复杂,它做了它应该做的事情。我把你的答案标为解决办法。
public class DayRateComparer : IEqualityComparer<CareRate>
{
public bool Equals(CareRate x, CareRate y) {
if (x = null) throw new ArgumentNullException(nameof(x));
if (y = null) throw new ArgumentNullException(nameof(y));
return x.Id == y.Id && x.DayRate == y.DayRate;
}
public int GetHashCode(CareRate obj) {
retun obj.Id.GetHashCode() + obj.DayRate.GetHashCode();
}
}
// Just a test method
public List<CareRate> FilterChangedCareRates(){
var currentCareRates = new List<CareRate>{
new CareRate { Id = 1, DayRate = 3,33, Description = "Some descr" },
new CareRate { Id = 2, DayRate = 4,44, Description = "Some other descr" }
};
var updatedCareRates = new List<CareRate>{
new CareRate { Id = 1, DayRate = 2,22 },
new CareRate {Id = 2, DayRate = 4,44 } // Unchanged
};
return updatedCareRates.Except(currentCareRates, new DayRateComparer()).ToList();
}