【问题标题】:C# Linq using arrays inside whereC# Linq 在 where 中使用数组
【发布时间】:2020-02-18 14:02:10
【问题描述】:

我想输出文件名数组中的所有值,并通过 Where 指令将它们过滤掉。我试图循环它。问题是,这些值显示了两次。

var files = from file in Directory.EnumerateFiles(Path, "*.TXT", SearchOption.AllDirectories)
            from line in File.ReadLines(file)
            where line.Contains(Filename[i])
            select new
            {
                File = file,
                Line = line
            };
foreach (var line in files)
{
    Console.WriteLine($"{line.Line}");
}

我的逻辑有问题还是我使用 Linq 有问题?

【问题讨论】:

  • 您能否edit 您的问题包括一些示例输入(即您正在处理的文件及其内容的代表性列表)和示例输出?
  • 尝试创建最小复制集。例如,定位一个包含单个文件的目录。在这种情况下,值是否显示两次?
  • 文件名可能出现在多个子文件夹中。那么你想包含完整的路径名以使文件名唯一吗?或者使用 Distinct() 过滤重复项?
  • 我不会评论你的算法应该做什么以及有哪些可能的优化,但你需要意识到字符串aabc.txt包含字符串abc.txt。跨度>
  • 您能用简单的英语描述一下这个问题吗?所以你在一些path中有*.txt文件;现在你想枚举文件这样(请问条件是什么?)

标签: c# arrays linq


【解决方案1】:

问题编辑后:

使用此代码获取现有文件:

var txtPath = Path.Combine(dirPath, txtFileName);
var txtLines = File.ReadAllLines(txtPath).ToList();
var filesFound = from file in Directory.EnumerateFiles(dirPath, "*.DST", SearchOption.AllDirectories)
                 where txtLines.Contains(Path.GetFileName(file))
                 select new
                 {
                     File = file,
                     Line = Path.GetFileName(file)
                 };

foreach (var line in filesFound)
    Console.WriteLine($"{line.Line}");

使用此代码获取丢失的文件(名称):

var existingFiles = filesFound.Select(s => s.Line).ToList();
var missingFiles = txtLines.Except(existingFiles);

或者:

var txtPath = Path.Combine(dirPath, txtFileName);
var txtLines = File.ReadAllLines(txtPath).ToList();
var filesMissing = txtLines.Except(from file in Directory.EnumerateFiles(dirPath, "*.DST", SearchOption.AllDirectories)
                                   where txtLines.Contains(Path.GetFileName(file))
                                   select Path.GetFileName(file));

foreach (var line in filesMissing)
    Console.WriteLine(line);

第二个的性能至少要好两倍。尤其是如果您根本不需要 filePath --> 因为丢失的文件没有文件。


对于原始问题:

也许您有重复,因为您的 foder 中有 2 个文件但您使用相同的文件名进行检查,或者您的文件中有 2 行与文件名匹配。

回答你的问题更重要的是:

您想过滤掉其中有自己名称的文件,还是想只获取所有文件中都有自己名称的文件

你选择了前者,所以解决方法:

var files = from file in Directory.EnumerateFiles(path, "*.TXT", SearchOption.AllDirectories)
            from line in File.ReadLines(file)
            where !line.Contains(System.IO.Path.GetFileName(file))  //note the exclamation mark, this is how you filter
            select new
            {
                File = file,
                Line = line
            };

foreach (var line in files)
    Console.WriteLine($"{line.Line}");

您可能注意到您不需要数组。

【讨论】:

  • 我不想进入 Foreach 循环,因为它会显示我的输出两次
  • 它只显示两次,因为你有 FileName[i],其中 i 总是 0,不是因为 foreach 本身。
  • 我在我的循环中修改它,看看底部的 i++;它过滤文件名 [0] 和文件名 [1] 的问题,但过滤后的内容确实在第二轮循环中停止播放
  • 我认为复制在那里,因为它们是两个文件 K420161.Txt 和一个 K464202.TXT 并且在 foreach 内,显示循环是 2x 触发的,一次使用过滤器,其他时间没有但我不能放出 1. Foreach 因为它运行 .对象数组。我不能放出显示循环,因为它在文件上运行,
  • 过滤掉里面有自己名字的文件,
猜你喜欢
  • 2011-02-28
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多