2013-07-08 3 views
8

Zum leichteren Authoring ich meine Hash wie folgt zu schreiben:einen Hash mit Array-Invertierung Werte

h = { 
    :key1: [:val1, :val2, :val3], 
    :key2: [:val4, :val5, :val6] 
} 

Aber überall Ich benutze es mir den Schlüssel mit einem Wert zugeordnet nachschlagen muß. Zur Zeit mache ich folgendes es zu transformieren:

h = Hash[*{ 
    :key1: [:val1, :val2, :val3], 
    :key2: [:val4, :val5, :val6] 
}.map {|key, vals| vals.map {|val| [val, key]}}.flatten] 

Was gibt mir, was ich will:

{ :val1 => :key1, :val2 => key1, :val3 => key1, :val4 => key2, :val5 => :key2, :val6 => :key2 } 

Aber gibt es einen einfacheren Weg, um das gleiche Ziel zu erreichen?

Antwort

10

Array # Produkt ist ziemlich Badass dafür. :)

h = { 
    key1: [:val1, :val2, :val3], 
    key2: [:val4, :val5, :val6] 
} 

p Hash[h.flat_map {|k,v| v.product [k]}] 
# {:val1=>:key1, :val2=>:key1, :val3=>:key1, :val4=>:key2, :val5=>:key2, :val6=>:key2} 
+2

* + 1 * viel besser .. :) –

+0

Ich denke, es ist eine lesbare und effiziente Lösung im Vergleich zu anderen –

+0

Nizza. Vielen Dank. – Johnsyweb

2

Ich habe gerade gestern versucht, dies zu tun. Dies war meine Lösung:

h = { 
key1: [:val1, :val2, :val3],  
key2: [:val4, :val5, :val6],  
} 
=> {:key1=>[:val1, :val2, :val3], :key2=>[:val4, :val5, :val6]} 

hp = {} 
=> {} 

h.each { |k, v| v.each{ |e| hp[e] = k } } 
=> {:key1=>[:val1, :val2, :val3], :key2=>[:val4, :val5, :val6]} 

hp 
=> {:val1=>:key1, 
:val2=>:key1, 
:val3=>:key1, 
:val4=>:key2, 
:val5=>:key2, 
:val6=>:key2} 
3
h = { 
    :key1 => [:val1, :val2, :val3], 
    :key2 => [:val4, :val5, :val6] 
} 

p Hash[h.flat_map{|k,v| v.zip [k]*v.size }] 
# >> {:val1=>:key1, :val2=>:key1, :val3=>:key1, :val4=>:key2, :val5=>:key2, :val6=>:key2} 
p Hash[h.flat_map{|k,v| v.zip [k].cycle }] 
# >> {:val1=>:key1, :val2=>:key1, :val3=>:key1, :val4=>:key2, :val5=>:key2, :val6=>:key2} 
+0

Ich denke, der Code ist schwer zu lesen (daher für Produktionssysteme schwer zu pflegen). Aber es ist cool und kurz :) (+1) – tessi

+2

Sehr cool. 'v.zip ([k] * v.größe)' könnte vereinfacht werden zu 'v.zip ([k] .cycle)'. –

+0

@undur_gongor Netter Usecase, den ich heute für '# cycle' gesehen habe. Vielen Dank. –