不区分大小写的列表搜索

问题描述 投票:130回答:8

我有一个列表testList,其中包含一串字符串。我只想在列表中尚不存在新字符串时才将其添加到testList中。因此,我需要对列表进行不区分大小写的搜索并使其高效。我不能使用Contains,因为这没有考虑到大小写。由于性能原因,我也不想使用ToUpper/ToLower。我遇到了这种方法,该方法有效:

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

这有效,但它也匹配部分单词。如果列表中包含“山羊”,我无法添加“燕麦”,因为它声称“燕麦”已经在列表中。有没有一种方法可以以不区分大小写的方式有效地搜索列表,而单词必须完全匹配?谢谢

c# list search case-insensitive
8个回答
160
投票

而不是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");

322
投票

我意识到这是一篇老文章,但是以防万一其他人正在寻找,您可以通过提供不区分大小写的字符串相等比较器来使用Contains,如下所示:

using System.Linq;

// ...

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

根据msdn,从.net 2.0开始提供。


18
投票

基于上面的Adam Sills答案-这是一个包含Contains ...的不错的扩展方法::]

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

8
投票

您可以使用StringComparer:

    var list = new List<string>();
    list.Add("cat");
    list.Add("dog");
    list.Add("moth");

    if (list.Contains("MOTH", StringComparer.OrdinalIgnoreCase))
    {
        Console.WriteLine("found");
    }

1
投票

基于Lance Larsen的回答-这是带有建议字符串的扩展方法。比较而不是string。等于

强烈建议您使用具有StringComparison参数的String.Compare重载。这些重载不仅使您可以定义所需的确切比较行为,使用它们还可以使您的代码对其他开发人员更具可读性。 [Josh Free @ BCL Team Blog]

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

0
投票

您正在检查IndexOf的结果是否大于或等于0,这意味着匹配是否在字符串中以anywhere]开始。尝试检查它是否等于到0:

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

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

为了避免所有这些复杂情况,您可以使用字典而不是列表。它们的键将是小写字符串,而值将是真实字符串。这样,性能就不会受到损害,因为您不必为每个比较都使用ToLower,但是您仍然可以使用Contains


0
投票

下面是在整个列表中搜索关键字并删除该项目的示例:


-1
投票

我有一个类似的问题,我需要该项目的索引,但是它必须不区分大小写,我在网上浏览了几分钟,却一无所获,所以我只是写了一个小方法来完成它,这是我做了什么:

© www.soinside.com 2019 - 2024. All rights reserved.