【问题标题】:Generate new List<string> based on substring match in List<string> in c#在 C# 中根据 List<string> 中的子字符串匹配生成新的 List<string>
【发布时间】:2017-05-15 11:36:21
【问题描述】:

考虑一个c#List&lt;string&gt; files,内容如下

C:\z1\z1.docx
C:\z1\z2.docx
C:\z2\z2.docx    // <--- file z2.docx has the same name as in folder z1.

我现在想查找所有具有相同文件名的文件并收到一个包含完整路径+文件名

的列表

List&lt;string&gt; duplicates

C:\z1\z2.docx
C:\z2\z2.docx

我在问,因为用循环和其他低效方式编写解决方案很容易,但我想使用一个优雅的解决方案,而且我对 c# 中的列表操作的了解还不够。

【问题讨论】:

  • 利用LINQ

标签: c# list substring


【解决方案1】:

我不确定你认为循环会效率低下 - 无论如何,这就是 LINQ 会在幕后做的事情。但是如果你想使用 LINQ,你可以通过几个方法调用来实现:

var result = files.GroupBy(p => Path.GetFileName(p))
                  .Where(g => g.Count() > 1)
                  .SelectMany(g => g);

它将首先按文件名分组,丢弃所有只有 1 个元素的组,并将剩余的组扁平化为单个路径集合。

您可以在SelectMany 之后添加ToList 调用以将结果具体化为List&lt;string&gt;

【讨论】:

  • 反对者愿意发表评论吗?它会根据样本输入/输出准确返回 OP 所期望的。
【解决方案2】:
List<string> duplicates = new List<string>() { @"C:\z1\z1.docx",
                                            @"C:\z1\z2.docx", @"C:\z2\z2.docx" };
        List<dynamic> GetList(List<string> FilesToCheck)
        {
            var Files = from file in FilesToCheck
                        where duplicates.Contains(file)
                        select new { FileName = new FileInfo(file).Name, FullName      
                        = new FileInfo(file).FullName };
            return Files.ToList();
        }

【讨论】:

  • where duplicates.Contains(file) 将始终为真,因为file 是从duplicates 开始的。
  • 对包含在提供的列表中的文件来说是正确的。这是他所要求的,也是优雅的。你的解决方案也不错。
  • 对不起,我想你误解了我的意思。这将总是为真,因为您正在迭代列表中的元素,然后检查该元素是否存在于同一个列表中。你只是把它从列表中拿出来,所以它必须在那里......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-31
  • 2012-12-17
相关资源
最近更新 更多