C# 一种优雅的方法,用于检查列表中是否包含一个属性相同的对象,并且仅当另一个属性的日期更晚时才进行替换
我的课程如下:C# 一种优雅的方法,用于检查列表中是否包含一个属性相同的对象,并且仅当另一个属性的日期更晚时才进行替换,c#,.net,linq,list,comparison,C#,.net,Linq,List,Comparison,我的课程如下: Object1{ int id; DateTime time; } 我有一个Object1列表。我想循环浏览另一个Object1列表,搜索具有相同ID的Object1,如果时间值晚于列表中的时间值,则将其替换到第一个列表中。如果项目不在第一个列表中,则添加它 我相信有一种优雅的方法可以做到这一点,也许可以使用linq?: List<Object1> listOfNewestItems = new List<Object1>(); List&l
Object1{
int id;
DateTime time;
}
我有一个Object1
列表。我想循环浏览另一个Object1
列表,搜索具有相同ID的Object1
,如果时间值晚于列表中的时间值,则将其替换到第一个列表中。如果项目不在第一个列表中,则添加它
我相信有一种优雅的方法可以做到这一点,也许可以使用linq?:
List<Object1> listOfNewestItems = new List<Object1>();
List<Object1> listToCycleThrough = MethodToReturnList();
foreach(Object1 object in listToCycleThrough){
if(listOfNewestItems.Contains(//object1 with same id as object))
{
//check date, replace if time property is > existing time property
} else {
listOfNewestItems.Add(object)
}
List listofNewstitems=new List();
List listToCycleThrough=MethodToReturnList();
foreach(ListToCycleThrow中的Object1对象){
if(listofNewstitems.Contains(//object1,id与对象相同))
{
//检查日期,如果时间属性>现有时间属性,则替换
}否则{
添加(对象)
}
很明显,这是非常混乱的(甚至没有检查更混乱的属性…),有更干净的方法吗?这是如何检查:
foreach(var object in listToCycleThrough)
{
var currentObject = listOfNewestItems
.SingleOrDefault(obj => obj.Id == object.Id);
if(currentObject != null)
{
if (currentObject.Time < object.Time)
currentObject.Time = object.Time
}
else
listOfNewestItems.Add(object)
}
foreach(listToCycleThrough中的var对象)
{
var currentObject=ListofNewstitems
.SingleOrDefault(obj=>obj.Id==object.Id);
if(currentObject!=null)
{
if(currentObject.Time
但是,如果您有大量数据,建议您在最新列表中使用字典
,查找时间将是O(1)而不是O(n)您可以使用LINQ。获取设置差异(最新),并使用连接
查找较新的对象
var listOfNewestIDs = listOfNewestItems.Select(o => o.id);
var listToCycleIDs = listToCycleThrough.Select(o => o.id);
var newestIDs = listOfNewestIDs.Except(listToCycleIDs);
var newestObjects = from obj in listOfNewestItems
join objID in newestIDs on obj.id equals objID
select obj;
var updateObjects = from newObj in listOfNewestItems
join oldObj in listToCycleThrough on newObj.id equals oldObj.id
where newObj.time > oldObj.time
select new { oldObj, newObj };
foreach (var updObject in updateObjects)
updObject.oldObj.time = updObject.newObj.time;
listToCycleThrough.AddRange(newestObjects);
请注意,您需要使用System.Linq;添加
这里有一个演示:我将创建一个字典
来查找Id的索引
,并使用它
var newItems = new List<Object1> { ...
IList<Object1> itemsToUpdate = ...
var lookup = itemsToUpdate.
Select((i, o) => new { Key = o.id, Value = i }).
ToDictionary(i => i.Key, i => i.Value);
foreach (var newItem in newitems)
{
if (lookup.ContainsKey(newitem.ID))
{
var i = lookup[newItem.Id];
if (newItem.time > itemsToUpdate[i].time)
{
itemsToUpdate[i] = newItem;
}
}
else
{
itemsToUpdate.Add(newItem)
}
}
var newItems=新列表{。。。
IList itemsToUpdate=。。。
var lookup=itemsToUpdate。
选择((i,o)=>new{Key=o.id,Value=i})。
ToDictionary(i=>i.Key,i=>i.Value);
foreach(newitems中的var newItem)
{
if(lookup.ContainsKey(newitem.ID))
{
var i=查找[newItem.Id];
if(newItem.time>itemsToUpdate[i].time)
{
itemsToUpdate[i]=newItem;
}
}
其他的
{
itemsToUpdate.Add(newItem)
}
}
这样,您就不需要为每个新项重新计算列表,您将受益于哈希查找性能
无论新项目列表中重复了多少次Id
,这都应该有效
var finalList = list1.Concat(list2)
.GroupBy(x => x.id)
.Select(x => x.OrderByDescending(y=>y.time).First())
.ToList();
下面是要测试的完整代码
public class Object1
{
public int id;
public DateTime time;
}
List<Object1> list1 = new List<Object1>()
{
new Object1(){id=1,time=new DateTime(1991,1,1)},
new Object1(){id=2,time=new DateTime(1992,1,1)}
};
List<Object1> list2 = new List<Object1>()
{
new Object1(){id=1,time=new DateTime(2001,1,1)},
new Object1(){id=3,time=new DateTime(1993,1,1)}
};
新列表中是否有多个具有相同ID的项目?在ListToCycleth中,可能有,在ListOfNewstitems中,不应该有(我试图在此仅输入最新的唯一ID值)
1 01.01.2001
2 01.01.1992
3 01.01.1993