【问题标题】:How to merge and update node of a list in c#如何在 C# 中合并和更新列表的节点
【发布时间】:2015-11-25 08:48:12
【问题描述】:

我知道关于 SO 的这个主题有很多通用问题。即使我尝试了一堆,但没有成功。 这是我用于合并的小代码

var existingFileDetails = XmlParser<NcSyncManifestXml>.Deserialize(RemoteManifestFile).Files;
var newList = existingFileDetails
   .Union(updatedFileDetails)
   .OrderByDescending(c => c.LastModifiedDate)
   .ToList();

我有两个列表,即List&lt;FileDetails&gt;. FileDetails 是一个包含三个东西Name, Md5Hash, LastModified 的类。这里我有两个列表,

List<FileDetails> UpdatedList = having 4-5 items of modified files, 
and another 
List<FileDetails> ExistingList = having 100 files 

场景

UpdatedList 中的文件可能存在于ExistingList 中。如果他们确实存在,他们有不同的

1. MD5Hash and 
2. LastModifiedDate

要求[更新]

假设: ExistingList = {[{FileName=xyx.txt,MD5=1,LastModified=12/12/2013}], [{FileName=abc.txt,MD5=11,LastModified=12/13/2013}],[{FileName=def.txt,MD5=111,LastModified=12/14/2013}], [{FileName=detf.txt,MD5=1111,LastModified=12/14/2013}]}

现在我收到一个新的更新文件列表,其中 abc.txt 和 def.txt 发生了变化,并添加了一个新文件 Run.txt

UpdatedList ={[{FileName=abc.txt,MD5=1fsd431,LastModified=12/16/2013}],[{FileName=def.txt,MD5=asdasd34243,LastModified=12/16/2013}]},[{FileName=Run.txt,MD5=sdf45sdf4545asdasd34243,LastModified=12/16/2013}]}

所以我合并后的新结果列表将是

NewList ={[{FileName=xyx.txt,MD5=1,LastModified=12/12/2013}], [{FileName=abc.txt,MD5=1fsd431,LastModified=12/16/2013}], // updated abc and def [{FileName=def.txt,MD5=asdasd34243,LastModified=12/16/2013}], //they have different md5 and date in UpdatedList [{FileName=detf.txt,MD5=1111,LastModified=12/14/2013}]}}]},[{FileName=Run.txt,MD5=sdf45sdf4545asdasd34243,LastModified=12/16/2013}]} // 添加新文件

问题

以上代码合并数据但不更新数据。需要你们去想办法。

【问题讨论】:

    标签: c# linq list collections


    【解决方案1】:

    您可以使用采用IEqualityComparerUnion linq 运算符的重载,以便它可以查看两个对象何时(在这种情况下是语义上)相同。由于我们总是更喜欢此处更新的文件详细信息,因此我们可以将其放置在操作符的左侧,以确保它们优先于现有文件详细信息。

    var newList = updatedFileDetails
        .Union(existingFileDetails, new FileParametersComparer())
        .OrderByDescending(a => a.LastModifiedDate)
        .ToList();
    

    文件参数比较器看起来像这样 - 这里我使用Name 属性来检查它是否引用同一个文件,尽管你可以做任何你需要的事情。

    public class FileParametersComparer : IEqualityComparer<FileDetails>
    {
        public bool Equals(FileDetails x, FileDetails y)
        {
            return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
        }
    
        public int GetHashCode(FileDetails obj)
        {
            return obj.Name.GetHashCode();
        }
    }
    

    小提琴:https://dotnetfiddle.net/AtJQvy

    【讨论】:

    • @AmitRanjan 我看不出您的更新如何使这个答案无效。您是否注意到他在拨打Union 时交换了updatedFileDetailsexistingFileDetails
    【解决方案2】:

    您可以通过将列表临时更改为字典来快速而肮脏地做到这一点:

    var tmpDict = ExistingList.ToDictionary(x => x.FileName);
    foreach (var item in UpdatedList)
    {
        tmpDict[item.FileName] = item;
    }
    
    var newList = tmpDict.Select(x => x.Value).OrderByDescending(c => c.LastModified).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多