webentwicklung-frage-antwort-db.com.de

Groß- und Kleinschreibung wird nicht berücksichtigt

Ich habe eine Liste testList, die eine Reihe von Zeichenfolgen enthält. Ich möchte eine neue Zeichenfolge nur dann in das testList einfügen, wenn sie noch nicht in der Liste vorhanden ist. Aus diesem Grund muss die Liste ohne Berücksichtigung der Groß- und Kleinschreibung durchsucht und effizienter gestaltet werden. Ich kann Contains nicht verwenden, da dies die Groß- und Kleinschreibung nicht berücksichtigt. Ich möchte auch nicht ToUpper/ToLower aus Performancegründen. Ich bin auf diese Methode gestoßen, die funktioniert:

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

Das funktioniert, aber es passt auch zu Teilwörtern. Wenn die Liste "Ziege" enthält, kann ich "Hafer" nicht hinzufügen, da behauptet wird, dass "Hafer" bereits in der Liste enthalten ist. Gibt es eine Möglichkeit, Listen unabhängig von Groß- und Kleinschreibung effizient zu durchsuchen, bei denen Wörter genau übereinstimmen müssen? Vielen Dank

118
Brap

Verwenden Sie anstelle von String.IndexOf String.Equals , um sicherzustellen, dass Sie keine partiellen Übereinstimmungen haben. Verwenden Sie FindAll auch nicht, da dies durch jedes Element geht. Verwenden Sie FindIndex (es stoppt bei dem ersten Treffer).

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

Verwenden Sie alternativ einige LINQ-Methoden (die auch bei der ersten angehalten werden, auf die sie zugreifen).

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

Mir ist klar, dass dies ein alter Beitrag ist, aber nur für den Fall, dass jemand anders auf der Suche ist, können Sie canContains verwenden, indem Sie den Vergleich für die Gleichheit von Strings in Groß- und Kleinschreibung wie folgt bereitstellen:

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

Dies ist seit .NET 2.0 gemäß msdn verfügbar.

305
shaxby

Basierend auf der obigen Antwort von Adam Sills - hier ist eine saubere Erweiterungsmethode für 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);
}

Sie können StringComparer verwenden:

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

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

Basierend auf der Antwort von Lance Larsen - hier ist eine Erweiterungsmethode mit der empfohlenen Zeichenfolge.Vergleichen Sie anstelle von string.Equals

Es wird dringend empfohlen, eine Überladung von String.Compare zu verwenden, die einen StringComparison-Parameter verwendet. Mit diesen Überladungen können Sie nicht nur das genaue, von Ihnen beabsichtigte Vergleichsverhalten definieren, sondern auch den Code für andere Entwickler besser lesbar machen. [ 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);
}
1
dontbyteme

Ich hatte ein ähnliches Problem, ich brauchte den Index des Artikels, aber die Groß- und Kleinschreibung musste nicht beachtet werden. Ich sah mich ein paar Minuten im Internet um und fand nichts. Deshalb habe ich nur eine kleine Methode geschrieben, um das zu erledigen tat:

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

Fügen Sie diesen Code derselben Datei hinzu und rufen Sie ihn folgendermaßen auf:

int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind);

Hoffe das hilft, viel Glück!

0

Sie überprüfen, ob das Ergebnis von IndexOf größer oder gleich 0 ist. Dies bedeutet, dass die Übereinstimmung irgendwo in der Zeichenfolge beginnt. Versuchen Sie zu überprüfen, ob es gleich bis 0 ist:

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

Jetzt stimmen "Ziege" und "Hafer" nicht mehr überein, aber "Ziege" und "Goa". Um dies zu vermeiden, können Sie die Längen der beiden Saiten vergleichen.

Um all diese Komplikationen zu vermeiden, können Sie anstelle einer Liste ein Wörterbuch verwenden. Der Schlüssel ist die Zeichenfolge in Kleinbuchstaben, und der Wert ist die echte Zeichenfolge. Auf diese Weise wird die Leistung nicht beeinträchtigt, da Sie nicht für jeden Vergleich ToLower verwenden müssen, aber Sie können trotzdem Contains verwenden.

0
Ilya Kogan