Case-Insensitive List Search
我有一个列表
1 2 3 | if(testList.FindAll(x => x.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0).Count > 0) Console.WriteLine("Found in list"); |
这是可行的,但它也匹配部分单词。如果列表中包含"goat",我就不能添加"oat",因为它声称"oat"已经在列表中。有没有一种方法可以有效地以不区分大小写的方式搜索列表,其中的单词必须完全匹配?谢谢
我知道这是一篇老文章,但是为了防止其他人看到,您可以使用
1 2 3 4 | if (testList.Contains(keyword, StringComparer.OrdinalIgnoreCase)) { Console.WriteLine("Keyword Exists"); } |
根据msdn,这是从.NET 2.0开始提供的。
使用string.equals而不是string.indexof,以确保没有部分匹配。另外,不要在每个元素中使用findall,使用findindex(它在第一个元素中停止)。
1 2 3 | if(testList.FindIndex(x => x.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) != -1) Console.WriteLine("Found in list"); |
交替使用一些LINQ方法(也会在它命中的第一个方法上停止)
1 2 | if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) ) Console.WriteLine("found in list"); |
基于上面的AdamSills答案-这里有一个很好的干净的contains扩展方法…:)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ///---------------------------------------------------------------------- /// <summary> /// Determines whether the specified list contains the matching string value /// </summary> /// <param name="list">The list.</param> /// <param name="value">The value to match.</param> /// <param name="ignoreCase">if set to <c>true</c> the case is ignored.</param> /// <returns> /// <c>true</c> if the specified list contais the matching string; otherwise, <c>false</c>. /// </returns> ///---------------------------------------------------------------------- public static bool Contains(this List<string> list, string value, bool ignoreCase = false) { return ignoreCase ? list.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase)) : list.Contains(value); } |
可以使用StringComparer:
1 2 3 4 5 6 7 8 9 | var list = new List<string>(); list.Add("cat"); list.Add("dog"); list.Add("moth"); if (list.Contains("MOTH", StringComparer.OrdinalIgnoreCase)) { Console.WriteLine("found"); } |
基于Lance Larsen的答案-这里有一个带有推荐字符串的扩展方法。比较而不是字符串。等于
It is highly recommended that you use an overload of String.Compare that takes a StringComparison parameter. Not only do these overloads allow you to define the exact comparison behavior you intended, using them will also make your code more readable for other developers. [Josh Free @ BCL Team Blog]
1 2 3 4 5 6 7 | public static bool Contains(this List<string> source, string toCheck, StringComparison comp) { return source != null && !string.IsNullOrEmpty(toCheck) && source.Any(x => string.Compare(x, toCheck, comp) == 0); } |
我有一个类似的问题,我需要这个项目的索引,但它必须是不区分大小写的,我环视了几分钟,没有发现任何东西,所以我只是写了一个小方法来完成它,我做了以下的事情:
1 2 3 4 5 6 7 8 9 10 11 | private static int getCaseInvariantIndex(List<string> ItemsList, string searchItem) { List<string> lowercaselist = new List<string>(); foreach (string item in ItemsList) { lowercaselist.Add(item.ToLower()); } return lowercaselist.IndexOf(searchItem.ToLower()); } |
将此代码添加到同一个文件中,然后这样调用它:
1 | int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind); |
希望这有帮助,祝你好运!
您正在检查indexof的结果是否大于或等于0,这意味着匹配是否从字符串中的任何位置开始。尝试检查它是否等于0:
1 2 3 | if (testList.FindAll(x => x.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0).Count > 0) Console.WriteLine("Found in list"); |
现在"山羊"和"燕麦"不匹配,但"山羊"和"果阿"会匹配。为了避免这种情况,您可以比较两个字符串的长度。
为了避免所有这些复杂性,您可以使用字典而不是列表。它们的键是小写字符串,值是真正的字符串。这样,性能不会受到影响,因为您不必在每次比较中使用