不区分大小写的列表search

我有一个包含一堆string的列表testList 。 我想添加一个新的string到testList只有当它不存在于列表中。 因此,我需要对列表进行不区分大小写的search,并使其高效。 我不能使用Contains因为这没有考虑到套pipe。 性能方面,我也不想使用ToUpper/ToLower 。 我碰到这种方法,这是有效的:

  if(testList.FindAll(x => x.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0).Count > 0) Console.WriteLine("Found in list"); 

这工作,但它也匹配部分单词。 如果列表包含“山羊”,我不能添加“燕麦”,因为它声称“燕麦”已经在列表中。 有没有办法有效地search名单不区分大小写的方式,其中单词必须完全匹配? 谢谢

而不是String.IndexOf,使用String.Equals来确保你没有部分匹配。 也不要使用FindAll,因为它会遍历每一个元素,使用FindIndex (它会停止它的第一个元素)。

 if(testList.FindIndex(x => x.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) != -1) Console.WriteLine("Found in list"); 

或者使用一些LINQ方法(它也会在第一个命令中停止)

 if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) ) Console.WriteLine("found in list"); 

我意识到这是一个旧的职位,但为了防止其他人正在寻找,你可以通过提供不区分大小写的string相等比较器使用Contains ,如下所示:

 if (testList.Contains(keyword, StringComparer.OrdinalIgnoreCase)) { Console.WriteLine("Keyword Exists"); } 

根据msdn,这已经可用.net 2.0。

基于上面的亚当基尔斯答案 – 这是一个很好的干净的扩展方法包含… 🙂

 ///---------------------------------------------------------------------- /// <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); } 

您正在检查IndexOf的结果是否大于或等于0,这意味着匹配是否在string中的任何位置开始。 尝试检查它是否等于 0:

 if (testList.FindAll(x => x.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0).Count > 0) Console.WriteLine("Found in list"); 

现在“山羊”和“燕麦”不匹配,但“山羊”和“果阿”会。 为了避免这种情况,您可以比较两个string的长度。

为了避免所有这些复杂,你可以使用一个字典,而不是一个列表。 他们的关键将是小写string,并且值将是真正的string。 这样,性能不会受到影响,因为您不必为每个比较使用ToLower ,但仍可以使用Contains

我有一个类似的问题,我需要项目的索引,但它必须不区分大小写,我环顾networking几分钟,什么都没发现,所以我只是写了一个小方法来完成它,这是我做:

 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()); } 

将此代码添加到同一个文件,并像这样调用它:

 int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind); 

希望这有帮助,祝你好运!

基于兰斯Larsen答案 – 这是一个扩展方法与推荐的string.Compare而不是string.Equals

强烈build议您使用带StringComparison参数的String.Compare的重载。 这些重载不仅允许您定义准确的比较行为,而且使用它们还可以使其他开发人员更易读。 [ Josh免费@ BCL团队博客 ]

 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); }