2011-08-21 22 views
30

que tienen este conjunto de hashes:¿Cómo puedo agrupar esta matriz de hashes?

- :name: Ben 
    :age: 18 
- :name: David 
    :age: 19 
- :name: Sam 
    :age: 18 

que necesito para agruparlos por age, por lo que terminan así:

18: 
- :name: Ben 
    :age: 18 
- :name: Sam 
    :age: 18 
19: 
- :name: David 
    :age: 19 

He intentado hacerlo de esta manera:

array = array.group_by &:age 

pero aparece este error:

NoMethodError (undefined method `age' for {:name=>"Ben", :age=>18}:Hash): 

¿Qué estoy haciendo mal? Estoy usando Rails y Ruby 3.0.1 1.9.2

Respuesta

77

El &:age significa que el método group_by debe llamar al método age sobre los elementos para obtener el grupo de datos. Este método age no está definido en los elementos que son Hashes.

Esto debería funcionar:

array.group_by { |d| d[:age] } 
2
out = {} 
array_of_hashes.each do |a_hash| 
    out[a_hash[:age]] ||= [] 
    out[a_hash[:age]] << a_hash 
end 

o

array.group_by {|item| item[:age]} 
0

Como otros han señalado método de rubí Symbol#to_proc se invoca y llama al método age en cada almohadilla de la matriz. El problema aquí es que los valores hash no responden a un método age.

Ahora podríamos definir uno para la clase Hash, pero probablemente no lo queremos para cada instancia de hash en el programa. En su lugar simplemente podemos definir el método age en cada almohadilla de la matriz de esta manera:

array.each do |hash| 
    class << hash 
    def age 
     self[:age] 
    end 
    end 
end 

Y entonces podemos utilizar group_by simplemente como antes:

array = array.group_by &:age 
Cuestiones relacionadas