如何在忽略文件扩展名的同时 return 设置两个 FileInfo 列表之间的差异?
How can I return the set diffrence between two FileInfo lists while ignoring the file extension?
我有两个 IEnumerable<FileInfo>
列表要比较:
IEnumerable<FileInfo> list1 = dir1.GetFiles("*" + _ext1, SearchOption.AllDirectories);
IEnumerable<FileInfo> list2 = dir2.GetFiles("*" + _ext2, SearchOption.AllDirectories);
其中 _ext1 和 _ext2 是不同的文件扩展名类型。例如:
string _ext1 = ".jpg";
string _ext2 = ".png";
所以 list1
看起来像:
file1.jpg
file2.jpg
file3.jpg
file4.jpg
file5.jpg
file6.jpg
和 list2
看起来像:
file1.png
file2.png
file4.png
我想在 list2 中找到 list1 中不存在的所有内容。我尝试了以下方法:
List<string> list1FileNames = list1.Select(f => Path.GetFileNameWithoutExtension(f.FullName)).ToList();
List<string> list2FileNames = list2.Select(f => Path.GetFileNameWithoutExtension(f.FullName)).ToList();
var setDiff = list1FileNames .Except(list2FileNames );
这很好,工作正常 returns(注意没有文件扩展名):
file3
file5
file6
但是,我真正想要的是获取 FileInfo 的列表,而不仅仅是 FileName 字符串。我需要这个,因为我需要其他信息,如 FullFile 路径、ext.. 所以只是一个文件名字符串列表将无法完成这项工作。我该怎么做呢?
您可以将 Where()
与 All()
一起使用,但时间复杂度较高:
var difference = list2
.Where(f=>list1.All(x=>Path.GetFileNameWithoutExtension(x.FullName) != Path.GetFileNameWithoutExtension(f.FullName));
怎么样:
IEnumerable<FileInfo> list1 = dir1.GetFiles("*" + _ext1, SearchOption.AllDirectories);
IEnumerable<FileInfo> list2 = dir2.GetFiles("*" + _ext2, SearchOption.AllDirectories);
IEnumerable<FileInfo> filtered = list2.Where(f2 => !list1.Any(f1 =>
Path.GetFileNameWithoutExtension(f1.FullName) == Path.GetFileNameWithoutExtension(f2.FullName)));
如果您追求速度,试试这个:
private IEnumerable<FileInfo> GetUniqueFilesWithoutExtension(IEnumerable<FileInfo> list1, IEnumerable<FileInfo> list2)
{
var d = new HashSet<string>();
foreach (var fi in list2)
{
d.Add(Path.GetFileNameWithoutExtension(fi.FullName));
}
foreach (var fi in list1)
{
if (!d.Contains(Path.GetFileNameWithoutExtension(fi.FullName)))
{
yield return fi;
}
}
}
从 list2
创建文件名(无扩展名)的哈希集,然后遍历 list1
并且仅 return 文件名(无扩展名)不符合的项目t 出现在 list2
的哈希集中。 yield return
允许您使用以流式方式发现的结果,而不必等待生成整个列表(如果这对您很重要)。
我有两个 IEnumerable<FileInfo>
列表要比较:
IEnumerable<FileInfo> list1 = dir1.GetFiles("*" + _ext1, SearchOption.AllDirectories);
IEnumerable<FileInfo> list2 = dir2.GetFiles("*" + _ext2, SearchOption.AllDirectories);
其中 _ext1 和 _ext2 是不同的文件扩展名类型。例如:
string _ext1 = ".jpg";
string _ext2 = ".png";
所以 list1
看起来像:
file1.jpg
file2.jpg
file3.jpg
file4.jpg
file5.jpg
file6.jpg
和 list2
看起来像:
file1.png
file2.png
file4.png
我想在 list2 中找到 list1 中不存在的所有内容。我尝试了以下方法:
List<string> list1FileNames = list1.Select(f => Path.GetFileNameWithoutExtension(f.FullName)).ToList();
List<string> list2FileNames = list2.Select(f => Path.GetFileNameWithoutExtension(f.FullName)).ToList();
var setDiff = list1FileNames .Except(list2FileNames );
这很好,工作正常 returns(注意没有文件扩展名):
file3
file5
file6
但是,我真正想要的是获取 FileInfo 的列表,而不仅仅是 FileName 字符串。我需要这个,因为我需要其他信息,如 FullFile 路径、ext.. 所以只是一个文件名字符串列表将无法完成这项工作。我该怎么做呢?
您可以将 Where()
与 All()
一起使用,但时间复杂度较高:
var difference = list2
.Where(f=>list1.All(x=>Path.GetFileNameWithoutExtension(x.FullName) != Path.GetFileNameWithoutExtension(f.FullName));
怎么样:
IEnumerable<FileInfo> list1 = dir1.GetFiles("*" + _ext1, SearchOption.AllDirectories);
IEnumerable<FileInfo> list2 = dir2.GetFiles("*" + _ext2, SearchOption.AllDirectories);
IEnumerable<FileInfo> filtered = list2.Where(f2 => !list1.Any(f1 =>
Path.GetFileNameWithoutExtension(f1.FullName) == Path.GetFileNameWithoutExtension(f2.FullName)));
如果您追求速度,试试这个:
private IEnumerable<FileInfo> GetUniqueFilesWithoutExtension(IEnumerable<FileInfo> list1, IEnumerable<FileInfo> list2)
{
var d = new HashSet<string>();
foreach (var fi in list2)
{
d.Add(Path.GetFileNameWithoutExtension(fi.FullName));
}
foreach (var fi in list1)
{
if (!d.Contains(Path.GetFileNameWithoutExtension(fi.FullName)))
{
yield return fi;
}
}
}
从 list2
创建文件名(无扩展名)的哈希集,然后遍历 list1
并且仅 return 文件名(无扩展名)不符合的项目t 出现在 list2
的哈希集中。 yield return
允许您使用以流式方式发现的结果,而不必等待生成整个列表(如果这对您很重要)。