如何确定集合中的任何元素是否出现在LINQ的字符串中?

时间:2017-05-31 17:44:41

标签: c# linq

我有Dictionary<string, List<string>>个对象。 Key表示文件的名称,ValueList<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

编辑我非常好奇为什么这个被投票并被标记为“过于宽泛”而被关闭。我提出了一个非常具体的问题,提供了我的代码,样本数据和样本数据的预期输出。

2 个答案:

答案 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.
            }
        }
    }
}

我没有输入,因此无法轻松测试代码或正则表达式,但它应该给出方法和简化的一般想法。