我有一個方法,使用一個「搜索字符串」可執行文件執行簡單的'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