2010-11-12 2 views
5

Ho il seguente hash rubino:Rubino Hash recepire

h = { i1: { q1: 1, q2:2 }, i2: { q1: 3, q2: 4} } 

e voglio recepirla nel modo seguente:

{ q1: { i1: 1, i2: 3 }, q2: { i1: 2, i2: 4 } } 

Ora, mi si avvicinò con una funzione che fa quello che voglio, ma mi chiedo se c'è un modo più succinto/elegante per la stessa cosa?

La mia soluzione:

ht = Hash.new{ |h,k| h[k] = {} } 

h.each_pair do |k,ih| 
    ih.each_pair{ |ik, iv| ht[ik][k] = iv } 
end 
+0

che è già molto succinta. Hai un esempio reale di quando vuoi trasformare l'hash in quel modo? –

+0

Ho praticamente la stessa struttura dati (solo più grande) con indicatori (i1, i2, ...) e i loro valori in alcune date (q1, q2, q3, ....). Non sono ancora sicuro che dovrei usare qui un array bidimensionale (in realtà sto ancora valutando entrambe le versioni ...) –

+0

Se fai spesso questo tipo di giocoleria, potresti trovare più facile usare Sqlite. –

risposta

2

Se preferite inject, è possibile scrivere come

h.inject({}){|a,(k,v)| 
    v.inject(a){|a1,(k1,v1)| 
    a1[k1] ||= {} 
    a1[k1][k] = v1 
    a1 
    } 
    a 
} 
+0

Sì, fa lo stesso, solo con inject, anche se penso che il primo modo per farlo sia leggermente più leggibile (Nella funzione reale devo includere poche altre righe di codice come la gestione delle eccezioni ecc ...) –

+0

Hai usato una specie di biblioteca di minificazione su questo blocco di codice? Sembra più bello :) – scaryguy