2011-01-14 12 views
6

Estoy buscando una colección simple que almacenará un montón de cadenas en una manera insensible a manera. Necesito al menos un método Contains() y Remove() para ver si una determinada cadena está presente y para eliminar esa cadena.Se busca: .Net colección que almacena un montón de cadenas insensibles a las mayúsculas de forma rápida y eficiente

He intentado List<string> pero ese es sensible a mayúsculas y minúsculas. Necesito podría utilizar un caso insensible Dictionary<TKey, T>, pero que "se siente" como una pérdida de espacio. Hacer un ToLower() en cada cadena es una pérdida de rendimiento.

¿Alguien sabe qué tipo de colección .Net debo usar?

+0

Cuando dices "un montón de cuerdas", ¿de cuántos estamos hablando? –

+0

Puede utilizar una lista como lo intentó anteriormente y pasar en StringComparer.OrdinalIgnoreCase como indicaba SLaks al llamar contiene –

+0

+/- 10k de elementos y tendré que consultar esta colección con bastante frecuencia. –

Respuesta

18

Debe usar un new HashSet<string>(StringComparer.OrdinalIgnoreCase).
Tenga en cuenta que este es un conjunto desordenado.

+0

¿Cuál es la implicación del rendimiento de un conjunto desordenado? ¿Hay una versión ordenada por ahí? –

+0

Las colecciones desordenadas siempre serán más rápidas que sus contrapartes ordenadas, debido a los requisitos más laxos. – Blindy

+1

La documentación dice que Contiene y Quita son operaciones O (1). http://msdn.microsoft.com/en-us/library/bb383091%28v=VS.90%29.aspx – Greg

2

Puede usar StringDictionary.

+3

Eso es un desperdicio de valores. – SLaks

+0

Claro, supongo que si no te está marcando con texto que es diferente de la inserción de texto, tal vez no sea apropiado. – Reddog

+0

todavía tenemos el problema de los valores dobles en la memoria. –

-1

Escriba sus propios métodos Contains() y Remove(), que realizan la comparación de mayúsculas y minúsculas.

+0

¿Cuál es la solución más rápida que HashSet que se ha sugerido? –

+0

Probablemente no lo es. – Nate

+0

Contiene el método de extensión que requiere que un comparador ya exista en el marco. –

0

Tuve el mismo problema para resolver hoy. Si puede incluir Linq, su Lista se sobrecargará con un comparador.

using System.Linq; 

List<string> stringList = new List<string>(); 
stringList.Contains("hello", StringComparer.OrdinalIgnoreCase); 

Espero que esto ayude: Martin

+0

Desafortunadamente LINQ es 3.5 y estoy desarrollando para 2.0. El problema con su solución es que el contenido tomará O (N) y me falta una función de eliminación. Parece que el HashSet dará el mejor rendimiento. –

0

Por diccionario por defecto no son sensibles al caso. Pero puede implementar su propia variante para hacerlo insensible. (Podría estar equivocado en esto: D)

Tuve el mismo problema con el Diccionario pero después de probar muchas implementaciones de IEquality, finalmente resolví el puntaje con LINQ.

string k = customers.Where(c => c.Key.Equals(valueToSearch, StringComparison.OrdinalIgnoreCase)).FirstOrDefault().Key; 

if (!string.IsNullOrEmpty(k) && k.ToUpper() == valueToSearch.ToUpper()) 
{ 
    // Do some thing 
} 

Espero que esto ayude a alguien en el futuro.

Sanjay Zalke

+0

Gracias por tu comentario. El problema con el diccionario es que tienes un par de clave/valor. Solo necesito saber si la cuerda está presente. No hay necesidad de la parte de 'valor'. Entonces, usar un diccionario desperdiciará espacio en la memoria. –

+0

Hola Kees, esta implementación no está relacionada solo con el diccionario, pero es LINQ, por lo que se aplica a todos los objetos en .NET, incluidas las bases de datos. Si tiene uso de lista: [código] (cadena k = clientes.Dónde (c => c.Equals (valueToSearch, StringComparison.OrdinalIgnoreCase)). FirstOrDefault();) –

+0

Ah lo tengo. El problema es que estoy usando .Net 2.0. Todavía parece que el 'nuevo HashSet (StringComparer.OrdinalIgnoreCase)' es el más rápido ya que es O (1). Tu código usa a para, lo que lo convierte en O (N). –

Cuestiones relacionadas