如何使用LINQ过滤字符串数组?

3

I have the following code:

string[] projects = Directory.GetDirectories(dir, "*", SearchOptions.TopDirectoryOnly);
string[] issues = Directory.GetFiles(dir, "*.txt", SearchOptions.AllDirectories)

foreach (string project in projects)
{
    var filteredIssues = from fi in issues where fi.Contains(project) select new { f = fi };

    foreach(string issue in filteredIssues)
    {
        // do something
    }
}

但是这段代码无法编译,会出现以下错误:

无法将类型“AnonymousType#1”转换为“string”

我参考了这个示例:http://www.dotnetlearners.com/linq/linq-to-string-array-with-example.aspx 和这个 Stack Overflow 问题:如何使用 LINQ Contains(string[]) 而不是 Contains(string) 但我不确定在那个特定的情况下 uid 是什么,也不知道如何将解决方案应用到我的问题上。
我还尝试了:
var filteredIssues = issues.Select(x => x.Contains(project)).ToArray();

但是它返回一个布尔数组。 dir 指向一个名为“Projects”的文件夹,其中包含 N 个唯一命名的文件夹。每个文件夹中都包含一个“Active”和一个“Archived”文件夹,其中包含任意数量的文本文件(即 issues 包含的内容,我想要筛选出基于项目的 issues 并将它们分组加载到UI中)。
最终,我想要得到这个 SQL 语句的 LINQ 等效语句:
SELECT issue FROM issues WHERE issue LIKE '%project%'

尽管我现在写这篇文章时意识到,我可以在第一个foreach循环中使用string[] issues = Directory.GetFiles(project, "*.txt", SearchOptions.AllDirectories)来获取文件数组,而不是在外面。但我仍然好奇如何根据包含另一个值的值来过滤字符串集合。

1
尝试使用以下代码:foreach(var issue in filteredIssues){ Console.WriteLine(issue.f); } - Eser
1
很少有匿名类型只有一个属性的情况。因此,您可以使用 select fi 代替 select new { f = fi } - Dennis_E
2
那么,var filteredIssues = issues.Where(x => x.Contains(project)).ToArray(); 是什么意思? - SimonGates
@Dennis_E 谢谢,我对LINQ一点经验都没有,所以我不知道我可以这样做。 - sab669
@SimonGates 看起来可以,如果你想把它作为答案发布,那我就可以接受并关闭这个案例。 - sab669
@sab669 已完成,附带一点关于使用 Select() 的说明 :) - SimonGates
3个回答

4
您可以使用Where来过滤集合。如下所示:
  var filteredIssues = issues.Where(x => x.Contains(project)).ToArray()

Select用于将一个IEnumerbale<Type>映射到另一个IEnumerbale<Type2>。可以将其视为映射,您可以挑选要映射到目标类型的内容。


3
您实际需要的是位于顶级目录以外的文本文件。
var projects = Directory.GetDirectories(dir, "*", SearchOptions.TopDirectoryOnly);
var issues = projects.SelectMany(p => 
        Directory.EnumerateFiles(p, "*.txt", SearchOptions.AllDirectories));
foreach(var issue in issues)
{
    // Do something;
}

我不完全确定你的意思。而且我可能表达不清楚,我应该说我只是试图过滤路径包含Project的issues,而不是文件名本身。因此,最终如果我有ProjectA和Project B,问题可能包含../ProjectA/Active/123.txt../ProjectB/Archived/456.txt - sab669
@sab669,我明白了,你实际上想要的是我回答中的后半部分。 - Jodrell

2

我认为你应该尝试这个。

string[] projects = Directory.GetDirectories(dir, "*", SearchOptions.TopDirectoryOnly);
string[] issues = Directory.GetFiles(dir, "*.txt", SearchOptions.AllDirectories)

foreach (string project in projects)
{
    var filteredIssues = from fi in issues where fi.Contains(project) select fi;

    foreach(string issue in filteredIssues)
    {
        // do something
    }
}

你应该选择 fi 而不是 select new { f = fi }; 其中 select new { f = fi } 是一个匿名类型,具有一个字符串属性名称为 f, 这就是为什么匿名类型转换为字符串失败的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接