Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一种优雅的方法,用于检查列表中是否包含一个属性相同的对象,并且仅当另一个属性的日期更晚时才进行替换_C#_.net_Linq_List_Comparison - Fatal编程技术网

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