如何在忽略文件扩展名的同时 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 允许您使用以流式方式发现的结果,而不必等待生成整个列表(如果这对您很重要)。