2013-07-08 14 views
8

Per facilità di authoring che sto scrivendo il mio hash come questo:Inversione un hash con array di valori

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

Ma ovunque io usarlo ho bisogno di cercare la chiave associata con un valore. Attualmente sto facendo la seguente per trasformarla:

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

che mi dà quello che voglio:

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

Ma c'è un modo più semplice per raggiungere lo stesso obiettivo?

risposta

10

Array # prodotto è abbastanza tosta per questo. :)

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 * molto meglio .. :) –

+0

Penso che sia una soluzione leggibile ed efficiente rispetto ad altri –

+0

Nice. Grazie. – Johnsyweb

2

stavo cercando di fare proprio questo ieri. Questa è stata la mia soluzione:

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

Penso che il codice sia difficile da leggere (quindi, difficile da mantenere per i sistemi di produzione). Ma è bello e breve :) (+1) – tessi

+2

Molto bello. 'v.zip ([k] * v.size)' potrebbe essere semplificato in 'v.zip ([k] .cycle)'. –

+0

@undur_gongor Nice usecase che ho visto oggi per '# cycle'. Grazie mille. –

Problemi correlati