2015-04-21 10 views
5

Mam skrót z wieloma kluczami i ciąg znaków, który nie zawiera żadnego lub jednego z kluczy w haszdzie.Sprawdź, czy ciąg zawiera którekolwiek z kluczy w haszdzie i zwróć wartość klucza, który zawiera

h = {"k1"=>"v1", "k2"=>"v2", "k3"=>"v3"} 
s = "this is an example string that might occur with a key somewhere in the string k1(with special characters like (^&*$#@!^&&*))" 

Jaki byłby najlepszy sposób na sprawdzenie, czy s zawiera jeden z klawiszy w h a jeśli tak, to zwróci wartość klucza, który zawiera ona?

Na przykład dla powyższych przykładów h i s, wyjście powinno być v1.

Edycja: zdefiniowany byłby tylko ciąg znaków. Hash zawsze będzie taki sam.

Odpowiedz

5

znajdę ten sposób czytelny:

hash_key_in_s = s[Regexp.union(h.keys)] 
p h[hash_key_in_s] #=> "v1" 

Lub w jednym wierszu:

p h.fetch s[Regexp.union(h.keys)] #=> "v1" 

A oto wersja nie za pomocą wyrażenia regularnego:

p h.fetch(h.keys.find{|key|s[key]}) #=> "v1" 
+0

Bardzo podoba mi się trzecia opcja - dzięki! – Sid

+0

Jakoś opuściłem twoją odpowiedź wcześniej. –

3

utworzyć regex z Hash h klucze i match w ciąg:

h[s.match(/#{h.keys.join('|')}/).to_s] 
# => "v1" 

lub jako Amadan zasugerował użycie Regexp#escape dla bezpieczeństwa:

h[s.match(/#{h.keys.map(&Regexp.method(:escape)).join('|')}/).to_s] 
# => "v1" 

Jeśli String s został równomiernie rozmieszczone, mogliśmy Zrobiłem też coś takiego:

s = "this is an example string that might occur with a key somewhere in the string k1 (with special characters like (^&*$\#@!^&&*))" 
h[(s.split & h.keys).first] 
# => "v1" 
+4

('h.keys.map & Regexp.method (: escape)). Join ('|') 'dla bezpieczeństwa, chyba że klucze są w rzeczywistości wyrostkami regularnymi. – Amadan

+0

Tak, to jest lepsze, dziękuję :) – shivam

+0

Powinieneś najpierw uzyskać 'klucz', a następnie uzyskać' h [klucz] 'jeśli' klucz' nie jest 'nil', na wypadek, gdyby ciąg nie zawierał żadnego z kluczy skrótu. Zamiast używać 'join' (co jest w porządku), możesz zrobić pierwszy krok w następujący sposób:' key = s [Regexp.union (h.keys.map (& Regexp.method (: escape))]] => " k1 "'. Jeszcze jedno: dobra odpowiedź! –

Powiązane problemy