我有Dictionary<string, List<string>>
个对象。 Key
表示文件的名称,Value
是List<string>
,表示文件中某些方法的名称。
我遍历字典并使用Key
从文件中读取数据。我正在尝试在此文件中查找包含Values
对象中的元素的行:
static void FindInvalidAttributes(Dictionary<string, List<string>> dictionary)
{
//Get the files from my controller dir
List<string> controllers = Directory.GetFiles(controllerPath, "*.cs", SearchOption.AllDirectories).ToList<string>();
//Iterate over my dictionary
foreach (KeyValuePair<string, List<string>> entry in dictionary)
{
//Build the correct file name using the dictionary key
string controller = Path.Combine(ControllerPath, entry.Key + "Controller.cs");
if (File.Exists(controller))
{
//Read the file content and loop over it
string[] lines = File.ReadAllLines(controller);
for (int i = 0; i < lines.Count(); i++)
{
//loop over every element in my dictionary's value (List<string>)
foreach (string method in entry.Value)
{
//If the line in the file contains a dictionary value element
if (lines[i].IndexOf(method) > -1 && lines[i].IndexOf("public") > -1)
{
//Get the previous line containing the attribute
string verb = lines[i - 1];
}
}
}
}
}
}
必须有一种更简洁的方法来实现if (File.Exists(controller))
语句中的代码。我不想在foreach
内部for
内嵌foreach
内部string
。
问题:如何使用LINQ确定List<string>
是否包含lines[0] = "public void SomeMethod()";
lines[1] = "public void SomeOtherMethod()";
List<string> myList = new List<string>();
myList.Add("SomeMethod");
myList.Add("AnotherMethod");
中的任何元素?
请注意,这两个值并不相同;字符串的一部分应包含整个列表元素。我能够找到大量的示例来查找列表元素中的字符串,但这不是我想要做的。
示例:
lines[0]
使用上述数据,FindInvalidAttributes
应该会导致我的myList
方法查看上一行,因为此字符串包含lines[1]
中的第一个元素。 SomeOtherMethod
不会导致方法检查上一行,因为myList
中没有显示IEnumerator
。
编辑我非常好奇为什么这个被投票并被标记为“过于宽泛”而被关闭。我提出了一个非常具体的问题,提供了我的代码,样本数据和样本数据的预期输出。
答案 0 :(得分:1)
如果lines
包含文件中的所有行,entry.Value
作为要查找的字词列表,则以下内容将返回包含entry.Value
中至少一个字的所有行:
var result = lines.Where(l => l.Split(' ').Intersect(entry.Value).Any());
或更多您的具体示例:
var result =
lines.Where(l =>
l.Trim().StartsWith("public") && entry.Value.Any(l.Contains));
答案 1 :(得分:1)
您可以构建一个正则表达式,一次性查找文件列表中的所有项目。
另请注意,您根本没有使用controllers
变量。
static void FindInvalidAttributes(Dictionary<string, List<string>> dictionary)
{
//Get the files from my controller dir
List<string> controllers = Directory.GetFiles(controllerPath, "*.cs", SearchOption.AllDirectories).ToList<string>();
//Iterate over my dictionary
foreach (var entry in dictionary)
{
//Build the correct file name using the dictionary key
string controller = Path.Combine(ControllerPath, entry.Key + "Controller.cs");
if (File.Exists(controller))
{
var regexText = "(?<attribLine>.*)\n" + string.Join("|", entry.Value.Select(t => "[^\n]*public\s[^\n]*" + Regex.Escape(t)))
var regex = new Regex(regexText)
//Read the file content and loop over it
var fileContent = File.ReadAllText(controller);
foreach (Match match in regex.Matches(fileContent))
{
// Here, match.Groups["attribLine"] should contain here what you're looking for.
}
}
}
}
我没有输入,因此无法轻松测试代码或正则表达式,但它应该给出方法和简化的一般想法。