如何在c#中合并和更新列表的节点

时间:2015-08-31 10:30:04

标签: c# linq list collections

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

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

我有两个列表,即List<FileDetails>. 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}]} //添加了新文件

问题

上面的代码合并数据但不更新它。需要你们弄清楚。

2 个答案:

答案 0 :(得分:3)

您可以使用Union linq运算符的重载,该运算符采用IEqualityComparer,以便它可以看到两个对象(在本例中是语义)相同的时间。由于我们始终更喜欢此处更新的文件详细信息,因此我们可以将其放在操作员的左侧,以确保它们优先于现有文件详细信息。

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

答案 1 :(得分:0)

您可以通过暂时将列表更改为词典来快速而肮脏:

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();