2015-04-21 9 views
5

Ho un hash con più chiavi e una stringa che non contiene nessuno o una delle chiavi nell'hash.Controlla se una stringa include una delle chiavi in ​​un hash e restituisce il valore della chiave che contiene

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 (^&*$#@!^&&*))" 

Quale sarebbe il modo migliore per controllare se s contiene uno qualsiasi dei tasti in h e se lo fa, restituiscono il valore della chiave che contiene?

Ad esempio, per gli esempi precedenti di h e s, l'output deve essere v1.

Modifica: solo la stringa verrà definita dall'utente. L'hash sarà sempre lo stesso.

risposta

5

Trovo questo modo leggibile:

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

O in una sola riga:

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

E qui è una versione non usare regexp:

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

Mi piace molto la terza opzione - grazie! – Sid

+0

Ho in qualche modo perso la tua risposta prima. –

3

creare un'espressione regolare di Hash h chiavi e match in stringa:

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

o come Amadan ha suggerito di utilizzare Regexp#escape per la sicurezza:

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

Se String s era equamente distanziati, potremmo Ho fatto qualcosa di simile a questo:

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 ('|') 'per sicurezza a meno che le chiavi non siano, di fatto, espressioni regolari. – Amadan

+0

sì, è meglio, grazie :) – shivam

+0

Dovresti prima ottenere il 'chiave', quindi ottenere' h [chiave] 'se' chiave' non è 'nil', nel caso in cui la stringa non contenga alcuna delle chiavi dell'hash. Piuttosto che usare 'join' (che va bene), potresti fare il primo passo in questo modo:' key = s [Regexp.union (h.keys.map (& Regexp.method (: escape)))] => " k1" '. Un'altra cosa: bella risposta! –

Problemi correlati