【问题标题】:Check for name of a directory from an array从数组中检查目录的名称
【发布时间】:2021-10-19 01:59:25
【问题描述】:

我正在开发一个程序,该程序应该扫描特定目录以查找其中具有特定名称的任何目录,如果找到它们,请告诉用户。

目前,我加载其搜索的名称的方式是这样的:

static string path = Path.Combine(Directory.GetCurrentDirectory(), @"database.txt");
static string[] database = File.ReadAllLines(datapath);

我将其用作在查看特定目录时要查找的名称数组。我正在使用 foreach 方法这样做。

System.IO.DirectoryInfo di = new DirectoryInfo("C:\ExampleDirectory");
        foreach (DirectoryInfo dir in di.GetDirectories())
        {

        }

有没有办法查看文件“database.txt”中的任何名称是否与“C:\ExampleDirectory”中找到的任何目录名称相匹配?

我能想到的唯一方法是:

System.IO.DirectoryInfo di = new DirectoryInfo(versionspath);
        foreach (DirectoryInfo dir in di.GetDirectories())
        {
            if(dir.Name == //Something...) {
            Console.WriteLine("Match found!");
            break;}
        }

但这显然行不通,我想不出任何其他方法来做到这一点。任何帮助将不胜感激!

【问题讨论】:

  • if (database.Contains(dir.Name)) { ... }

标签: c# arrays directory match


【解决方案1】:

您可以使用 LINQ 来执行此操作

var allDirectoryNames = di.GetDirectories().Select(d => d.Name);
var matches = allDirectoryNames.Intersect(database);

if (matches.Any())
    Console.WriteLine("Matches found!");

在第一行我们得到所有目录名,然后我们使用Intersect() 方法查看allDirectoryNamesdatabase 中都存在哪些目录名

【讨论】:

    【解决方案2】:

    像往常一样,LINQ 是要走的路。每当您必须在两个列表之间以及两个列表包含不同类型之间查找匹配或不匹配时,您必须使用.Join().GroupJoin()

    .Join() 发挥作用,如果您需要找到 1:1 关系,.GroupJoin() 用于任何类型的 1-to 关系(1:0、1:many 或 1:1)。

    因此,如果您需要与您的列表匹配的目录,这听起来很适合 .Join() 操作员:

    public static void Main(string[] args)
    {
        // Where ever this comes normally from.
        string[] database = new[] { "fOo", "bAr" };
        string startDirectory = @"D:\baseFolder";
    
        // A method that returns an IEnumerable<string>
        // Using maybe a recursive approach to get all directories and/or files
        var candidates = LoadCandidates(startDirectory);
    
        var matches = database.Join(
            candidates,
            // Simply pick the database entry as is.
            dbEntry => dbEntry,
            // Only take the last portion of the given path.
            fullPath => Path.GetFileName(fullPath),
            // Return only the full path from the given matching pair.
            (dbEntry, fullPath) => fullPath,
            // Ignore case on comparison.
            StringComparer.OrdinalIgnoreCase);
    
        foreach (var match in matches)
        {
            // Shows "D:\baseFolder\foo"
            Console.WriteLine(match);
        }
    
        Console.ReadKey();
    }
    
    private static IEnumerable<string> LoadCandidates(string baseFolder)
    {
        return new[] { @"D:\baseFolder\foo", @"D:\basefolder\baz" };
        //return Directory.EnumerateDirectories(baseFolder, "*", SearchOption.AllDirectories);
    }
    

    【讨论】:

      【解决方案3】:

      根据您在 stackoverflow 上的其他问题,我认为您的问题是家庭作业,或者您是一个充满激情的爱好程序员,对吗?因此,我将尝试在此处继续您几乎完整的解决方案来解释原理。
      您将需要一个嵌套循环,一个循环中的循环。在外部循环中,您遍历目录。你已经得到了这个。对于每个目录,您需要遍历 database 中的名称以查看其中是否有任何项目与目录名称匹配:

      System.IO.DirectoryInfo di = new DirectoryInfo(versionspath);
      foreach (DirectoryInfo dir in di.GetDirectories())
      {
          foreach (string name in database)
          {        
              if (dir.Name == name)
              {
                  Console.WriteLine("Match found!");
                  break;
              }
          }
      }
      

      根据您的目标,您可能希望在第一个匹配目录处退出。上面的示例代码没有。单个break; 语句只退出内部循环,而不是外部循环。所以它继续检查下一个目录。尝试自己弄清楚如何在第一场比赛中停止(通过退出外循环)。

      【讨论】:

      • 我在堆栈上得到的最佳答案哈哈。是的,充满激情的业余爱好者(希望只要我能够获得动力,就成为一名学生,而 COVID 不会杀死我和我爱的每个人。)我认为我有一个解决方案,可以在第一场比赛中爆发(这是我理想中应该做的事情. 认为这是较早执行此操作的最佳方式,而不是遍历所有匹配项),虽然它可能不优雅,但它应该可以工作。非常感谢
      • 我很高兴它有帮助。快乐编码! ;)
      猜你喜欢
      • 1970-01-01
      • 2022-11-24
      • 2012-07-06
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多