2012-11-30 3 views
27

Ho due hash ...Come combinare un hash con un altro hash in Ruby

a = {:a => 5} 
b = {:b => 10} 

voglio ...

c = {:a => 5,:b => 10} 

Come posso creare hash c?

+0

appena preso in IRB – thefonso

+0

1.9.3p194: 001> hash1 = {: a => 5} = > {: a => 5} 1.9.3p1.9.3p194: 002> hash2 = {: b => 10} => {: b => 10} 1.9.3p194: 003> hash3 = hash1.merge (hash2) => {: a => 5,: b => 10} 1.9.3p194: 004> hash3 => {: a => 5,: b => 10} 1.9.3p194: 005> – thefonso

risposta

51

Si tratta di un'operazione piuttosto semplice in avanti se si sta solo interleaving:

c = a.merge(b) 

Se si desidera aggiungere in realtà i valori insieme, questo sarebbe un po 'più complicato, ma non impossibile:

c = a.dup 
b.each do |k, v| 
    c[k] ||= 0 
    c[k] += v 
end 

Il motivo per a.dup è di evitare di maneggiare i valori nell'hash a, ma se non si cura è possibile saltare quella parte. Il ||= viene utilizzato per assicurarsi che inizi con un valore predefinito di 0 poiché nil + 1 non è valido.

2

Utilizzare il metodo di fusione:

c = a.merge b 
19

Come tutti dicono è possibile utilizzare il metodo di fusione per risolvere il problema. Tuttavia c'è un po 'di problemi con l'utilizzo del metodo di fusione. Ecco perché

person1 = {"name" => "MarkZuckerberg", "company_name" => "Facebook", "job" => "CEO"} 

person2 = {"name" => "BillGates", "company_name" => "Microsoft", "position" => "Chairman"} 

Dai un'occhiata a questi due campi nome e nome_azienda. Qui nome e company_name sono entrambi uguali nei due hash (intendo le chiavi). Il prossimo lavoro e la posizione hanno chiavi diverse.

Quando si tenta di unire due hash person1 e person2 Se le chiavi person1 e person2 sono uguali? quindi il valore chiave person2 sostituirà il valore chiave peron1. Qui il secondo hash sovrascriverà i primi campi hash perché entrambi sono uguali. Qui nome e ragione sociale sono gli stessi. Vedere il risultato

people = person1.merge(person2) 

Output: {"name"=>"BillGates", "company_name"=>"Microsoft", 
     "job"=>"CEO", "position"=>"Chairman"} 

Tuttavia, se non si desidera che il secondo hash esegua l'override del primo hash. Si può fare qualcosa di simile

people = person1.merge(person2) {|key, old, new| old} 

    Output: {"name"=>"MarkZuckerberg", "company_name"=>"Facebook", 
      "job"=>"CEO", "position"=>"Chairman"} 

E 'solo una breve nota quando si utilizza merge()

+1

, grazie per includere (altro) completa funzionalità di unione nel tuo re risposta accettabili! :) +1 – Zackkenyon

+0

sei il mio eroe per oggi. Stavo cercando esattamente questo. –

+0

Le collisioni sono importanti da considerare! Ma la tua soluzione è la stessa di 'people = person2.merge (person1)', giusto?In questo caso il blocco non è necessario, ma è utile se vuoi fare qualcosa di più complicato per le collisioni. È anche utile per "unire!" (La versione distruttiva). –