我有一个方法,使用一个“搜索字符串”可执行文件执行简单的'grep'跨文件。 (实际上,我正在做一个很天真“查找所有引用”)如何使用LINQ使C#“grep”更具功能性?
IEnumerable<string> searchStrings = GetSearchStrings();
IEnumerable<string> filesToLookIn = GetFiles();
MultiMap<string, string> references = new MultiMap<string, string>();
foreach(string fileName in filesToLookIn)
{
foreach(string line in File.ReadAllLines(fileName))
{
foreach(string searchString in searchStrings)
{
if(line.Contains(searchString))
{
references.AddIfNew(searchString, fileName);
}
}
}
}
注:MultiMap<TKey,TValue>
是大致相同Dictionary<TKey,List<TValue>>
,只是避免你通常会遇到的NullReferenceException异常。
我一直在试图把这个变成一个更“功能”的风格,使用链式LINQ扩展方法,但没有弄清楚。
一个死胡同尝试:
// I get lost on how to do a loop within a loop here...
// plus, I lose track of the file name
var lines = filesToLookIn.Select(f => File.ReadAllLines(f)).Where(// ???
而另一家(希望保存的文件名这个时候):
var filesWithLines =
filesToLookIn
.Select(f => new { FileName = f, Lines = File.ReadAllLines(f) });
var matchingSearchStrings =
searchStrings
.Where(ss => filesWithLines.Any(
fwl => fwl.Lines.Any(l => l.Contains(ss))));
但我仍然似乎失去我需要的信息。
也许我只是从错误的角度来解决这个问题?从性能角度来看,循环应该与原始示例的顺序大致相同。
任何想法如何在一个更紧凑的功能表示?
我不知道,你可以用多个“从”这样的语句。这实际上是如何工作的?我的LINQ经验纯粹是通过lambdas和扩展方法。这甚至转化为链式扩展方法吗? – 2009-07-14 02:45:02