c# - 如何比较两个 IEnumerable<> 对象并返回一个新对象?
问题描述
我想比较两个IEnumerable<>
对象并返回一个新IEnumerable<>
对象。
下面是我有对象的代码,newFiles
然后我有OriginalFiles
对象。我想比较这两个IEnumerable<>
对象并找到那些是新文件并且也有修改文件的文件。
FileConfig
类md5Hash
将每个文件的值作为一个字符串,所以我可以比较OriginalFiles
和newFiles
对象md5Hash
字符串以找出哪些文件已更改,然后IEnumerable<FileConfig>
使用这些修改的文件+新文件创建一个新对象。
例如:如果newFiles
对象总共有 10 个文件并且OriginalFiles
有 8 个文件,那么这意味着其中有两个新文件。然后剩下的 8 个,我将比较并查看使用md5Hash
字符串更改了哪些文件,所以如果 8 个文件中有 5 个文件更改并且还有两个新文件,那么我将返回 7 个文件作为IEnumerable<FileConfig>
对象。
public class ProcessFile
{
public IEnumerable<FileConfig> OriginalFiles { get; set; }
public IEnumerable<FileConfig> GetNewFiles(IEnumerable<FileConfig> newFiles)
{
// compare OriginalFiles and newFiles object and return a new IEnumerable<FileConfig> object
// which has only those files which are modified or new by comparing on md5Hash string
foreach (var element1 in newFiles)
{
var newFileName = element1.Name;
var newMd5Hash = element1.MD5Hash;
foreach (var element2 in this.OriginalFiles)
{
var originalFileName = element2.Name;
var originalmd5Hash = element2.MD5Hash;
if (newFileName.Equals(originalFileName, StringComparison.InvariantCultureIgnoreCase) && !newMd5Hash.Equals(originalmd5Hash, StringComparison.InvariantCultureIgnoreCase))
{
yield return new FileConfig
{
Name = newFileName,
Timestamp = element1.Timestamp,
MD5Hash = newMd5Hash
};
}
}
}
}
}
public class FileConfig
{
public string Name { get; set; }
public DateTime Timestamp { get; set; }
public string MD5Hash { get; set; }
}
我可以运行两个 for 循环并比较其md5Hash
字符串上的每个文件,并找出哪些文件已被修改并返回新IEnumerable<FileConfig>
对象,但是是否有任何快捷方式可以轻松完成相同的事情或在 C# 中以任何其他更好的方式?
解决方案
在我看来,您需要一个左外连接来获取新文件的情况和现有文件的更改。这应该这样做:
public IEnumerable<FileConfig> GetNewFiles(IEnumerable<FileConfig> newFiles) =>
from element1 in newFiles
join element2 in this.OriginalFiles
on element1.Name.ToLowerInvariant() equals element2.Name.ToLowerInvariant()
into g
where !g.Any() || !element1.MD5Hash.Equals(g.First().MD5Hash, StringComparison.InvariantCultureIgnoreCase)
select new FileConfig
{
Name = element1.Name,
Timestamp = element1.Timestamp,
MD5Hash = element1.MD5Hash,
};
如果您设置为FileConfig
只读,那么您可以这样做:
public IEnumerable<FileConfig> GetNewFiles(IEnumerable<FileConfig> newFiles) =>
from element1 in newFiles
join element2 in this.OriginalFiles
on element1.Name.ToLowerInvariant() equals element2.Name.ToLowerInvariant()
into g
where !g.Any() || !element1.MD5Hash.Equals(g.First().MD5Hash, StringComparison.InvariantCultureIgnoreCase)
select element1;
推荐阅读
- python - 如何监听币安智能链网络上的新交易?
- javascript - javascript数组中的索引超出范围
- sql-server - SQL查询将列总和添加到新行中
- c++ - UE4如何检查未初始化的指针?C++
- python - 如何删除 JSON 对象列表中给定值的重复项?
- javascript - 如何从 api 响应异步和 deepai 中保存图像
- r - 通过具有R中条件的组计算平均值的平均值
- javascript - Javascript按字母顺序排序div而不破坏CSS表单样式
- php - PHP:与 eval 相同
- javascript - Javascript 如何在 mysql 中使用 Async/Await