visual validar una studio saber net minusculas minuscula mayusculas mayuscula letra ignorar convertir comparar como cadenas c# .net hashset

c# - validar - Hacer que HashSet<cadena> no distinga entre mayúsculas y minúsculas



ignorar mayusculas y minusculas java (6)

Tengo un método con el parámetro HashSet. Y necesito hacer Contiene insensible a mayúsculas y minúsculas dentro de él:

public void DoSomething(HashSet<string> set, string item) { var x = set.Contains(item); ... }

¿Hay alguna forma de hacer que el HashSet existente no distinga entre mayúsculas y minúsculas (no cree uno nuevo)?

Estoy buscando una solución con el mejor rendimiento.

Editar

Contiene se puede llamar varias veces. Por lo tanto, las extensiones de IEnumerable no son aceptables para mí debido a su menor rendimiento que el método HashSetContiene.

Solución

Dado que, la respuesta a mi pregunta es NO, es imposible, he creado y utilizado el siguiente método:

public HashSet<string> EnsureCaseInsensitive(HashSet<string> set) { return set.Comparer == StringComparer.OrdinalIgnoreCase ? set : new HashSet<string>(set, StringComparer.OrdinalIgnoreCase); }


El HashSet<T> tiene una sobrecarga que le permite pasar un IEqualityComparer<string> . Hay algunos de estos definidos para usted ya en la clase estática StringComparer , algunos de los cuales ignoran el caso. Por ejemplo:

var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase); set.Add("john"); Debug.Assert(set.Contains("JohN"));

Tendrá que hacer este cambio al momento de construir el HashSet<T> . Una vez que existe, no puede cambiar el IEqualityComparer<T> que está usando.

Para que lo sepas, de forma predeterminada (si no pasas ningún IEqualityComparer<T> al constructor HashSet<T> ), utiliza EqualityComparer<T>.Default en EqualityComparer<T>.Default lugar.

Editar

La pregunta parece haber cambiado después de haber publicado mi respuesta. Si tiene que hacer una búsqueda que no HashSet<string> mayúsculas y minúsculas en una HashSet<string> sensible a mayúsculas y minúsculas , deberá realizar una búsqueda lineal:

set.Any(s => string.Equals(s, item, StringComparison.OrdinalIgnoreCase));

No hay forma de evitar esto.


El constructor de HashSet puede tomar un IEqualityComparer alternativo que puede anular cómo se determina la igualdad. Vea la lista de constructores here .

La clase StringComparer contiene un conjunto de instancias estáticas de IEqualityComparers para cadenas. En particular, probablemente estés interesado en StringComparer.OrdinalIgnoreCase . Here está la documentación de StringComparer .

Tenga en cuenta que otro constructor IEnumerable un IEnumerable , por lo que puede construir un nuevo HashSet partir del anterior, pero con el IEqualityComparer .

Entonces, todos juntos, quieren convertir su HashSet siguiente manera:

var myNewHashSet = new HashSet(myOldHashSet, StringComparer.OrdinalIgnoreCase);


No se puede hacer mágicamente que HashSet (o Diccionario) sensible a mayúsculas / minúsculas se comporte de una manera insensible a las mayúsculas y minúsculas.

HashSet recrear uno dentro de su función si no puede confiar en que el HashSet entrante no HashSet entre mayúsculas y minúsculas.

Código más compacto: use el constructor del conjunto existente:

var insensitive = new HashSet<string>( set, StringComparer.InvariantCultureIgnoreCase);

Tenga en cuenta que copiar HashSet es tan costoso como recorrer todos los elementos, por lo que si su función solo lo hace en la búsqueda, sería más barato (O (n)) repetir todos los elementos. Si su función se llama varias veces para hacer una búsqueda única insensible a mayúsculas y minúsculas, debería intentar pasar HashSet a ella en su lugar.


Si desea dejar en su lugar la versión original que distingue entre mayúsculas y minúsculas, puede consultarla con linq con insensibilidad de mayúsculas y minúsculas:

var contains = set.Any(a => a.Equals(item, StringComparison.InvariantCultureIgnoreCase));


Suponiendo que tienes este método de extensión:

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source) { return new HashSet<T>(source); }

Puedes usar esto:

set = set.Select(n => n.ToLowerInvariant()).ToHashSet();

O bien, podrías hacer esto:

set = new HashSet(set, StringComparer.OrdinalIgnoreCase); //or InvariantCultureIgnoreCase or CurrentCultureIgnoreCase


HashSet está diseñado para encontrar rápidamente elementos según su función de hash y comparación de igualdad. Lo que está pidiendo es realmente encontrar un elemento que concuerde con "algún otro" estado. Imagine que tiene un Set<Person> objetos Set<Person> que solo usa Person.Name para comparar y necesita encontrar un elemento con algún valor dado de Person.Age .

El punto es que necesita iterar sobre los contenidos del conjunto para encontrar los elementos coincidentes. Si va a hacer esto a menudo, puede crear un conjunto diferente, en su caso usando un comparador insensible a mayúsculas y minúsculas, pero luego debería asegurarse de que este conjunto de sombras esté sincronizado con el original.

Las respuestas hasta ahora son esencialmente variaciones de lo anterior, pensé agregar esto para aclarar el tema fundamental.