2009-07-23 5 views
0

У меня есть список:поиск объекта списка

Dim list As New List(Of String) 

со следующими пунктами:

290-7-11

1255-7-12

222- 7-11

290-7-13

Что такое простой и быстрый способ поиска, если в списке уже есть дубликат «первого блока» плюс «-» плюс «второй блок». Пример: пункт 290-7 появляется дважды, 290-7-11 и 290-7-13.

Я использую .net 2.0

ответ

4

Если вы хотите знать, если есть дубликаты, но не волнует, что они ...

Самый простой способ (предполагая, что ровно два дефиса).

Boolean hasDuplicatePrefixes = list 
    .GroupBy(i => i.Substring(0, i.LastIndexOf('-'))) 
    .Any(g => g.Count() > 1) 

Самый быстрый способ (по крайней мере, для больших наборов строк).

HashSet<String> hashSet = new HashSet<String>(); 

Boolean hasDuplicatePrefixes = false; 
foreach (String item in list) 
{ 
    String prefix = item.Substring(0, item.LastIndexOf('-')); 

    if (hashSet.Contains(prefix)) 
    { 
     hasDuplicatePrefixes = true; 
     break; 
    } 
    else 
    { 
     hashSet.Add(prefix); 
    } 
} 

Если есть случаи с более чем двумя штрихами, используйте следующее. Это будет продолжаться с одной тире.

String prefix = item.Substring(0, item.IndexOf('-', item.IndexOf('-') + 1)); 

В .NET 2.0 Dictionary<TKey, TValue> использования вместо HashSet<T>.

Dictionary<String, Boolean> dictionary= new Dictionary<String, Boolean>(); 

Boolean hasDuplicatePrefixes = false; 
foreach (String item in list) 
{ 
    String prefix = item.Substring(0, item.LastIndexOf('-')); 

    if (dictionary.ContainsKey(prefix)) 
    { 
     hasDuplicatePrefixes = true; 
     break; 
    } 
    else 
    { 
     dictionary.Add(prefix, true); 
    } 
} 

Если вы не заботитесь о читаемости и скорости, использовать массив вместо списка, и вы настоящий фанат регулярных выражений, вы можете сделать следующее тоже.

Boolean hasDuplicatePrefixes = Regex.IsMatch(
    String.Join("#", list), @".*(?:^|#)([0-9]+-[0-9]+-).*#\1"); 
+0

V.good. Код конечно помогает. – shahkalpesh

+0

HashSet? в котором есть версия .net? – shahkalpesh

+0

HashSet 3.5+ –

0

Вы хотите, чтобы остановить пользователя от добавления его?
Если это так, то может быть полезен HashTable с ключом как первый блок-блок.

Если нет, LINQ - это путь.
Но ему нужно будет пройти список для проверки.
Насколько велик этот список?

EDIT: Я не знаю, имеет ли HashTable общую версию.
Вы также можете использовать SortedDictionary, который может принимать общие аргументы.

+0

этот список не такой большой, 100 наименований макс. Я использую .net 2.0 –

+0

да. Я хочу, чтобы пользователь не добавил его. –

+0

Не беспокойся об этом. Поиск 100 предметов не будет болью. – shahkalpesh

0

Если вы список содержит только строки, то вы можете просто сделать метод, который принимает строку, которую вы хотите найти вместе со списком:

Boolean isStringDuplicated(String find, List<String> list) 
{ 
    if (list == null) 
     throw new System.ArgumentNullException("Given list is null."); 

    int count = 0; 

    foreach (String s in list) 
    { 
     if (s.Contains(find)) 
      count += 1; 

     if (count == 2) 
      return true; 
    } 

    return false; 
} 

Если вы номер имеет особое значение в вашей программе, не бойтесь использовать класс, чтобы представлять их вместо того, чтобы придерживаться строк. Тогда у вас будет место для написания всех пользовательских функций, которые вы хотите использовать для указанных номеров.

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