2011-01-14 7 views
6

Sto cercando una raccolta semplice che memorizzerà un gruppo di stringhe in senza distinzione tra maiuscole e minuscole. Ho bisogno di almeno un metodo Contains() e Remove() per vedere se una certa stringa è presente e per rimuovere quella stringa.Richiesto: raccolta .Net che memorizza un gruppo di stringhe senza distinzione tra maiuscole e minuscole veloce ed efficiente

Ho provato List<string> ma quello è case sensitive. Ho bisogno di usare una maiuscole e minuscole Dictionary<TKey, T>, ma questo "sembra" come uno spreco di spazio. Fare uno ToLower() su ogni stringa è uno spreco di prestazioni.

Qualcuno sa che tipo di raccolta .Net dovrei usare?

+0

Quando si dice "un mucchio di stringhe", quanti stiamo parlando? –

+0

È possibile utilizzare un elenco come si è tentato in precedenza e passare in StringComparer.OrdinalIgnoreCase come indicato da SLaks quando si chiama Contains –

+0

+/- 10k di elementi e sarà necessario eseguire il quiz di questa raccolta abbastanza frequentemente. –

risposta

18

È necessario utilizzare uno new HashSet<string>(StringComparer.OrdinalIgnoreCase).
Si noti che questo è un insieme non ordinato.

+0

Quali sono le implicazioni perfomance di un set non ordinato. Esiste una versione ordinata là fuori? –

+0

Le collezioni non ordinate saranno sempre più veloci delle loro controparti ordinate, a causa dei requisiti più labili. – Blindy

+1

La documentazione dice che Contiene e Rimuovi sono operazioni O (1). http://msdn.microsoft.com/en-us/library/bb383091%28v=VS.90%29.aspx – Greg

2

È possibile utilizzare uno StringDictionary.

+3

Questo è uno spreco di valori. – SLaks

+0

Certo, immagino che se non stai digitando un testo diverso dall'inserimento del testo, forse non è appropriato. – Reddog

+0

abbiamo ancora il problema dei doppi valori in memoria. –

-1

Scrivere i propri metodi Contains() e Remove(), che eseguono il confronto insensibile tra maiuscole e minuscole.

+0

Qual è la soluzione più veloce rispetto a HashSet che è stata suggerita? –

+0

Probabilmente no. – Nate

+0

Contiene il metodo di estensione che accetta un comparatore già esistente nel framework. –

0

Aveva lo stesso problema da risolvere oggi. Se riesci a includere Linq, la tua lista si sovraccarica di metodi con un comparatore.

using System.Linq; 

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

Spero che questo aiuti: Martin

+0

Purtroppo LINQ è 3.5 e sto sviluppando per 2.0. Il problema con la tua soluzione è che il contenitore avrà O (N) e mi manca una funzione di rimozione. Sembra che l'HashSet darà le migliori prestazioni. –

0

dizionario di default non sono case in-sensitive. Ma puoi implementare la tua variante per renderla in-sensitive. (Potrei sbagliarmi su questo: D)

Ho avuto lo stesso problema con Dizionario ma dopo aver provato molte implementazioni di IEquality, alla fine ho risolto il punteggio 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 
} 

Spero che questo possa aiutare qualcuno in futuro.

Sanjay Zalke

+0

Grazie per il tuo commento. Il problema con il dizionario è che hai una coppia chiave/valore. Ho solo bisogno di sapere se la stringa è presente. Non è necessario per la parte 'valore'. Quindi usare un dizionario sprecerebbe spazio nella memoria. –

+0

Ciao Kees, Questa implementazione non è affatto correlata solo al Dizionario, ma è LINQ quindi si applica a tutti gli oggetti in .net inclusi i Database. Se si utilizza la lista: [code] (string k = customers.Where (c => c.Equals (valueToSearch, StringComparison.OrdinalIgnoreCase)). FirstOrDefault();) –

+0

Ah, capito. Il problema è che sto usando .Net 2.0. Sembra ancora che "il nuovo HashSet (StringComparer.OrdinalIgnoreCase)" sia il più veloce in quanto è O (1). Il tuo codice usa un for, che lo rende O (N). –

Problemi correlati