2011-01-24 16 views
11

Chcę przeszukać moje klucze w słowniku z podobną funkcją. Chcę bierze klucze zacząć od „A” lub ich 3-ty list jest „e” lub ich 4RT list nie jest „d”: wyszukaj ciągi znaków o podobnej funkcji

w sql to jest możliwe napisanie zapytania "gdzie (klucz jak" ') i (key not like' d__ ') "Chcę mieć tę funkcję dla Dictionary. Masz jakąś sugestię algorytmu?

Dzięki!

Odpowiedz

11

ile będzie to odpowiednik SQL skanowanie tabeli, można użyć LINQ lub metod przedłużających IEnumerable<T> szukać słownika dla wszystkich wartości, których klucze pasujące do wzorca :

Extension Metoda:

var values = dictionary.Where(pv => 
      pv.Key.StartsWith("A") || 
      (pv.Key.Length >= 3 && pv.Key[2] == 'e') || 
      pv.Key.Length < 4 || 
      pv.Key[3] != 'd').Select(pv => pv.Value); 

LIN Pytanie:

var values = (from pv in dictionary 
       where pv.Key.StartsWith("A") || 
        (pv.Key.Legnth >= 3 && pv.Key[2] == 'e') || 
        pv.Length < 4 || 
        pv.Key[3] != 'd' 
        select pv.Value); 

Należy zauważyć, że ostatnia część obu tych predykatów odnosi się do "czwartej litery nie jest" d ". Uznałem, że łańcuch o długości trzech znaków (lub mniej) będzie pasował do tego. Jeśli masz na myśli co najmniej cztery znaki, a czwarty znak to nie "d", to zmiany powinny być oczywiste.

Należy pamiętać, że podstawową (wydajnościową) korzyścią dla klasy Dictionary jest użycie wyszukiwania klucza hash, które (w przeciętnym i najlepszym przypadku) to O (1). Użycie takiego wyszukiwania liniowego to O (n), więc coś takiego będzie na ogół wolniejsze niż zwykłe wyszukiwanie klucza.

+0

jesteś świetny!Dziękuję za odpowiedź ! – softwaremonster

2

Wystarczy użyć LINQ:

var query = myDict.Where(x => x.Key.IndexOf('a') > -1 && x.Key.IndexOf("d_") == -1); 
+0

'Select (x => x)' nic nie robi. O ile w rzeczywistym wyrażeniu LINQ wymagana jest instrukcja 'select', nie jest wymagana w kodzie, który używa tylko metod LINQ, chyba że faktycznie dokonujesz transformacji. Ponadto nie jest to zgodne z jego wymaganą logiką, ale przeszedłem z przegłosowaniem, ponieważ wskazuje on rzeczywistą koncepcję. –

+0

@Adam - Dziękuję za wskazanie. Mój Linq-fu wciąż potrzebuje rozwoju ... – Oded

10

można uzyskać dostęp właściwość Keys słownika, a następnie użyć kwerendy LINQ do oceny klucze:

var dictionary = new Dictionary<string,string>(); 

dictionary.Keys.Where(key => key.Contains("a")).ToList(); 
+3

Głosuję to, ale myślę, że ważne jest, abyśmy ponownie wykonali skan liniowy, aby zastosować tę ocenę. –

2

Można użyć LINQ

To coś takiego:

myDic.Where(d=>d.Key.StartWith("a")).ToDictionary(d=>d.Key,d=>d.Value) 

Albo

myDic.Where(d=>d.Key.Contains("b")).ToDictionary(d=>d.Key,d=>d.Value) 

Albo

myDic.Where(d=>some other condition with d.Key).ToDictionary(d=>d.Key,d=>d.Value) 
1

Oto mały przedłużenie I bita:

public static IList<string> KeysLikeAt(this Dictionary<string, object> dictionary, char letter, int index) 
{ 
    return dictionary.Where(k => k.Key.Length > index && k.Key[index] == letter) 
     .Select(k => k.Key).ToList(); 
} 

public static IList<string> KeysNotLikeAt(this Dictionary<string, object> dictionary, char letter, int index) 
{ 
    return dictionary.Where(k => k.Key.Length > index && k.Key[index] != letter) 
     .Select(k => k.Key).ToList(); 
} 

i można go używać tak:

IList<string> keysStartingWithA = dictionary.KeysLikeAt('a', 0); 

IList<string> keysNotStartingWithD = dictionary.KeysNotLikeAt('d', 0); 
+0

Po co właściwie przeprowadzać wyszukiwanie w ciągu znaków za pomocą 'IndexOf' zamiast używać tylko indeksu w klasie' string' (oczywiście przy sprawdzaniu długości)? –

+0

zaktualizowano przy użyciu sprawdzania długości: – hunter

+0

wielkość liter ma znaczenie, więc może być fajnie dodać ... – hunter

Powiązane problemy