significa que example create ruby mongodb hash mongodb-ruby

que - Hashes de grupo Ruby por valor de clave



ruby create hash (4)

Tengo una matriz, que sale por un método map / reduce realizado por MongoDB, se ve más o menos así:

[{"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>299.0}, {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>244.0}, {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>1.0, "count"=>204.0}, {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>510.0}, {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>437.0}, {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>469.0}, {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>477.0}, {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>481.0}, {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>401.0}, {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>468.0}, {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>448.0}, {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>0.0, "count"=>485.0}, {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "type"=>10.0, "count"=>518.0}]

Notarás que hay tres valores distintos para el type , en este caso 0 , 1 y 2 , que ahora quiero hacer es agrupar esta matriz de valores hash por el valor de su type clave, por ejemplo, esta matriz terminaría luciendo como :

{ :type_0 => [ {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>299.0}, {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>510.0}, {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>469.0}, {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>481.0}, {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>468.0}, {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>485.0} ], :type_1 => [ {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>204.0} ], :type_10 => [ {"minute"=>30.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>244.0}, {"minute"=>45.0, "hour"=>15.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>437.0}, {"minute"=>0.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>477.0}, {"minute"=>15.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>401.0}, {"minute"=>30.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>448.0}, {"minute"=>45.0, "hour"=>16.0, "date"=>5.0, "month"=>9.0, "year"=>2011.0, "count"=>518.0} ] }

así que sé que estas matrices de ejemplo son realmente grandes, pero creo que puede ser un problema más simple de lo que estoy imaginando

Así que, básicamente, cada matriz de hashes se agruparía por el valor de su clave de type , y luego se devolvería como un hash con una matriz para cada tipo, cualquier ayuda sería realmente útil, incluso algunos consejos útiles serían muy apreciados.


Algo como esto tal vez?

mangled = a.group_by { |h| h[''type''].to_i }.each_with_object({ }) do |(k,v), memo| tk = (''type_'' + k.to_s).to_sym memo[tk] = v.map { |h| h = h.dup; h.delete(''type''); h } end

O si no te importa conservar los datos originales:

mangled = a.group_by { |h| h[''type''].to_i }.each_with_object({ }) do |(k,v), memo| tk = (''type_'' + k.to_s).to_sym memo[tk] = v.map { |h| h.delete(''type''); h } # Drop the h.dup in here end


group_by recoge un enumerable en conjuntos, agrupados por el resultado de un bloque . No está obligado a obtener simplemente el valor de la clave en este bloque, por lo que si desea omitir el ''type'' en esos conjuntos, puede hacerlo, como en:

array.group_by {|x| "type_#{x.delete(''type'').to_i}".to_sym}

Esto dará como resultado exactamente lo que pediste.

Avanzado: Esto va un poco fuera del alcance de la pregunta, pero si desea conservar la matriz original, debe duplicar cada objeto dentro de ella. Esto hará el truco:

array.map(&:dup).group_by {|x| "type_#{x.delete(''type'').to_i}".to_sym}


array.group_by {|x| x[''type'']}

o si quiere las cosas clave de símbolo que podría incluso

array.group_by {|x| "type_#{x[''type'']}".to_sym}

Creo que esto expresa mejor "Así que, básicamente, cada matriz de hashes se agruparía por el valor de su clave de tipo , y luego se devolvería como un hash con una matriz para cada tipo ", incluso si deja la tecla :type sola en los hash de salida .


by_type = {} a.each do |h| type = h.delete("type").to_s # type = ("type_" + type ).to_sym by_type[ type ] ||= [] by_type[ type ] << h # note: h is modified, without "type" key end

Nota: teclas hash ligeramente diferentes aquí, utilicé los valores de tipo directamente como la clave

si debe tener las teclas hash como en su ejemplo, puede agregar la línea que está comentada.

PD: ¡Acabo de ver la solución de Tapio, es muy bonita y corta! Tenga en cuenta que solo funciona con Ruby> = 1.9