2014-09-18 15 views
6

mi piacerebbe tornare un array di hash basato sulla combinazione di sport e tipoRuby, hash unici in serie basati su più campi

Ho il seguente array:

[ 
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100 }, 
    { sport: "football", type: 11, othey_key: 700 }, 
    { sport: "basketball", type: 11, othey_key: 200 }, 
    { sport: "basketball", type: 11, othey_key: 500 } 
] 

I 'd piacerebbe tornare:

[ 
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100 }, 
    { sport: "basketball", type: 11, othey_key: 200 }, 
] 

ho cercato di usare (pseudocodice):

[{}, {}, {}].uniq { |m| m.sport and m.type } 

So di poter creare un array di questo tipo con i loop, sono abbastanza nuovo da Ruby e sono curioso di sapere se esiste un modo migliore (più elegante) per farlo.

+0

Sì, 'uniq' con un blocco è la strada da percorrere, ma ecco un altro modo:' arr.group_by {| h | [h [: sport], h [: tipo]]} .values.map (&: first) '. –

risposta

13

Provare a utilizzare Array#values_at per generare un array su uniq da.

sports.uniq{ |s| s.values_at(:sport, :type) } 
+1

Solo una piccola correzione: 'uniq' sta passando in ogni valore al blocco, quindi in questo caso è un 'Hash' e chiamerebbe [' Hash # values_at'] (http://ruby-doc.org /core/Hash.html#method-i-values_at). Basta fare attenzione se si dispone di una serie di elementi diversi da hash o array. –

5

Una soluzione è quella di costruire una sorta di chiave con lo sport e tipo, in questo modo:

arr.uniq{ |m| "#{m[:sport]}-#{m[:type]}" } 

Il modo uniq opere è che usa il valore di ritorno del blocco per confrontare gli elementi.

4
require 'pp' 

data = [ 
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100 }, 
    { sport: "football", type: 11, othey_key: 700 }, 
    { sport: "basketball", type: 11, othey_key: 200 }, 
    { sport: "basketball", type: 11, othey_key: 500 } 
] 

results = data.uniq do |hash| 
    [hash[:sport], hash[:type]] 
end 

pp results 

--output:-- 
[{:sport=>"football", :type=>11, :other_key=>5}, 
{:sport=>"football", :type=>12, :othey_key=>100}, 
{:sport=>"basketball", :type=>11, :othey_key=>200}]