/ / Ordenar hash de hashes por valor (y devolver el hash, no una matriz) - ruby, estructuras de datos, hash, clasificación

Ordenando Hash of Hashes por valor (y devuelva el hash, no una matriz) - ruby, estructuras de datos, hash, ordenando

Tengo el siguiente hash:

user = {
"user" => {
"title" => {"weight" => 1, .... }
"body" => {"weight" => 4, ....}
....
....
}
}

¿Es posible ordenar al Usuario por la clave de peso de sus hashes secundarios?

Miré en Hash.sort, pero parece que devuelve una matriz en lugar de mi hash original ordenado.

Respuestas

11 para la respuesta № 1

En Ruby 1.9, Hashes ordenado, pero Hash#sort todavía devuelve un Array de Arrays. ¡Imagina eso! Implica que puedes construir tu propio método de clasificación encima.

class Hash
def sorted_hash(&block)
self.class[sort(&block)]   # Hash[ [[key1, value1], [key2, value2]] ]
end
end

Hashno están clasificados en Ruby 1.8. Si desea compatibilidad con Ruby 1.8, puede usar ActiveSupport "s OrderedHash. Se comporta como un 1.9-Hashpara que puedas definir lo mismo sorted_hash método en él:

class ActiveSupport::OrderedHash
def sorted_hash(&block)
self.class[sort(&block)]
end
end

hash = ActiveSupport::OrderedHash.new
hash["b"] = "b"
hash["a"] = "a"
hash               #=> {"b"=>"b", "a"=>"a"}  => unsorted
hash.sorted_hash   #=> {"a"=>"a", "b"=>"b"}  => sorted!

Tienes que copiar el sorted_hash método a su código, porque no existe por defecto!

Actualización para clasificación profunda: Si está buscando ordenar algo más que la clave hash, pase un bloque al sorted_hash método de la siguiente manera (asumiendo la implementación desde arriba):

hash = ActiveSupport::OrderedHash.new
hash["a"] = { "attr" => "2", "..." => "..." }
hash["b"] = { "attr" => "1", "..." => "..." }

# Unsorted.
hash
#=> {"a"=>{"attr"=>"2", "..."=>"..."}, "b"=>{"attr"=>"1", "..."=>"..."}}

# Sort on the "attr" key. (Assuming every value is a Hash itself!)
hash.sorted_hash { |a, b| a[1]["attr"] <=> b[1]["attr"] }
#=> {"b"=>{"attr"=>"1", "..."=>"..."}, "a"=>{"attr"=>"2", "..."=>"..."}}

8 para la respuesta № 2

Los hashes son estructuras de datos fundamentalmente sin clasificar; Hash#sort es, de hecho, lo que quieres. O eso, u ordenar una lista de claves y luego usar eso para enumerar cuándo es el momento de generar el hash, en lugar de enumerar directamente sobre el hash usando sus propios métodos.