2011-01-14 9 views
6

Szukam prostej kolekcji, która będzie przechowywać wiele ciągów znaków w stylu w sposób niewrażliwy na wielkość liter. Potrzebuję przynajmniej metody Contains() i Remove(), aby sprawdzić, czy obecny łańcuch jest obecny i usunąć ten ciąg.Poszukiwana: kolekcja .Net, która przechowuje kilka niewrażliwych na wielkość znaków ciągów, jest szybka i wydajna.

Próbowałem już List<string>, ale w tym przypadku rozróżniana jest wielkość liter. Potrzebne może być użycie niewrażliwego na wielkość liter Dictionary<TKey, T>, ale "czuje się" jak marnowanie przestrzeni. Robienie ToLower() na każdym ciągu jest marnowaniem wydajności.

Czy ktoś wie, jakiego rodzaju kolekcja .Net powinienem użyć?

+0

Kiedy mówisz "gromadka strun", ilu mówimy? –

+0

Możesz użyć Listy tak, jak poprzednio próbowałeś i przekazywać StringComparer.OrdinalIgnoreCase, jak podano SLaksy podczas wywoływania Zawiera –

+0

+/- 10k elementów i będę musiał quizować tę kolekcję dość często. –

Odpowiedz

18

Powinieneś użyć new HashSet<string>(StringComparer.OrdinalIgnoreCase).
Pamiętaj, że jest to zestaw nieuporządkowany.

+0

Jakie są implikacje wykonania nieuporządkowanego zestawu. Czy istnieje tam uporządkowana wersja? –

+0

Nieuporządkowane kolekcje będą zawsze szybsze niż ich zamówione odpowiedniki ze względu na bardziej luźne wymagania. – Blindy

+1

Dokumentacja mówi, że Contains i Remove są operacjami O (1). http://msdn.microsoft.com/en-us/library/bb383091%28v=VS.90%29.aspx – Greg

2

Można użyć StringDictionary.

+3

To marnowanie wartości. – SLaks

+0

Jasne, domyślam się, że nie wpisujesz tekstu, który różni się od wstawiania tekstu, może nie jest odpowiedni. – Reddog

+0

nadal mamy problem z podwójnymi wartościami w pamięci. –

-1

Napisz własne metody Contains() i Remove(), które wykonują porównywanie niewrażliwe na wielkość liter.

+0

Jakie jest Twoje rozwiązanie szybsze niż sugerowany HashSet ? –

+0

Prawdopodobnie tak nie jest. – Nate

+0

Zawiera metodę rozszerzenia, która pobiera porównywalnik już istnieje w ramach. –

0

Miał ten sam problem do rozwiązania dzisiaj. Jeśli możesz włączyć Linq, to ​​twoja lista zostanie przeciążona metodami z porównywarką.

using System.Linq; 

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

Nadzieja to pomaga: Martin

+0

Niestety LINQ ma 3,5 i rozwijam się na 2.0. Problem z twoim rozwiązaniem polega na tym, że zawiera on O (N) i brakuje mi funkcji usuwania. Wygląda na to, że HashSet zapewni najlepszą wydajność. –

0

Domyślnie Słownik nie są rozróżniane w wrażliwych. Ale możesz zaimplementować swój własny wariant, aby był wrażliwy. (Mogę się mylić: D)

Miałem ten sam problem ze Słownikiem, ale potem po wypróbowaniu wielu implementacji IEquality, ostatecznie ustaliłem wynik z 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 
} 

Mam nadzieję, że to pomoże komuś w przyszłości.

Sanjay Zalke

+0

Dzięki za komentarz. Problem ze słownikiem polega na tym, że masz parę klucz/wartość. Muszę tylko wiedzieć, czy ciąg jest obecny. Nie ma potrzeby stosowania części "wartości". Używanie słownika marnowałoby więc pamięć. –

+0

Hi Kees, Ta implementacja w ogóle nie jest związana tylko ze Słownikiem, ale jest LINQ, więc odnosiła się do wszystkich obiektów w .net, w tym do baz danych. Jeśli masz listę użyj: [kod] (string k = customers.Where (c => c .Equals (valueToSearch, StringComparison.OrdinalIgnoreCase)). FirstOrDefault();) –

+0

Ah dostałem to. Problem polega na tym, że używam .Net 2.0. Nadal wydaje się, że "nowy HashSet (StringComparer.OrdinalIgnoreCase)" jest najszybszy, ponieważ jest O (1). Twój kod używa fora, co czyni go O (N). –

Powiązane problemy