2011-01-14 3 views
6

Я ищу простую коллекцию, которая будет хранить кучу строк в без учета регистра. Мне нужен хотя бы метод Contains() и Remove(), чтобы увидеть, существует ли определенная строка и удалить эту строку.Требуется: .Net коллекция, которая хранит кучу нечувствительных к регистру строк быстро и эффективно

Я пробовал List<string>, но этот вопрос чувствителен к регистру. Мне нужно было использовать регистр, нечувствительный Dictionary<TKey, T>, но это «чувствует», как пустая трата пространства. Выполнение ToLower() на каждой строке является пустой тратой производительности.

Кто-нибудь знает, какую .Net коллекцию я должен использовать?

+0

Когда вы говорите «куча струн», о чем мы говорим? –

+0

Вы можете использовать Список, как вы ранее пытались, и передать его в StringComparer.OrdinalIgnoreCase, поскольку SLaks указывается при вызове Содержит –

+0

+/- 10k элементов, и мне нужно будет довольно часто тестировать эту коллекцию. –

ответ

18

Вы должны использовать new HashSet<string>(StringComparer.OrdinalIgnoreCase).
Обратите внимание, что это неупорядоченный набор.

+0

Каковы особенности исполнения неупорядоченного набора. Есть ли там заказываемая версия? –

+0

Неупорядоченные коллекции всегда будут быстрее, чем их заказываемые копии, из-за более слабых требований. – Blindy

+1

В документации указано, что Contains and Remove являются операциями O (1). http://msdn.microsoft.com/en-us/library/bb383091%28v=VS.90%29.aspx – Greg

2

Вы можете использовать StringDictionary.

+3

Это пустая трата ценностей. – SLaks

+0

Несомненно, я думаю, что если вы не используете текст, отличный от текстовой вставки, возможно, это не подходит. – Reddog

+0

, мы все еще имеем проблему двойных значений в памяти. –

-1

Напишите свой собственный Contains() и Remove() методов, которые выполняют сравнение без регистра.

+0

Как ваше решение быстрее, чем предлагаемый HashSet ? –

+0

Это, вероятно, нет. – Nate

+0

Содержит метод расширения, который принимает сопоставитель, уже существует в рамках. –

0

Если бы такая же проблема решить сегодня. Если вы можете включить Linq, то ваш List перегружает методы с помощью сравнения.

using System.Linq; 

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

Надеется, что это помогает: Мартину

+0

К сожалению, LINQ - 3.5, и я разрабатываю для 2.0. Проблема с вашим решением заключается в том, что в содержимом будет принимать O (N), и мне не хватает функции удаления. Кажется, что HashSet даст лучшую производительность. –

0

По словарю умолчанию не учитывается в регистре. Но вы можете реализовать свой собственный вариант, чтобы сделать его чувствительным. (Возможно, я ошибаюсь в этом: D)

У меня была такая же проблема с Dictionary, но после того, как я попытался реализовать множество реализаций IEquality, я, наконец, установил счет с помощью 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 
} 

Надеюсь, это поможет кому-то в будущем.

Sanjay Zalke

+0

Спасибо за замечание. Проблема со словарем заключается в том, что у вас есть пара ключей/значений. Мне нужно только знать, присутствует ли строка. Нет необходимости в «стоимости». Таким образом, использование словаря будет избавлять от нехватки памяти. –

+0

Hi Kees. Эта реализация не связана только с Словарем, но это LINQ, поэтому она применяется ко всем объектам в .net, включая базы данных. Если у вас есть список, используйте: [code] (строка k = customers.Where (c => c.Equals (valueToSearch, StringComparison.OrdinalIgnoreCase)). FirstOrDefault();) –

+0

Ах получил. Проблема в том, что я использую .Net 2.0. По-прежнему кажется, что «новый HashSet (StringComparer.OrdinalIgnoreCase)» является самым быстрым, так как это O (1). В вашем коде используется значение for, что делает его O (N). –

Смежные вопросы