Comment trier un tableau de hachages par une valeur dans le hachage?

120

Ce code Ruby ne se comporte pas comme je m'y attendais:

# create an array of hashes
sort_me = []
sort_me.push({"value"=>1, "name"=>"a"})
sort_me.push({"value"=>3, "name"=>"c"})
sort_me.push({"value"=>2, "name"=>"b"})

# sort
sort_me.sort_by { |k| k["value"]}

# same order as above!
puts sort_me

Je cherche à trier le tableau de hachages par la clé "valeur", mais ils sont imprimés non triés.

Verre Ollie
la source

Réponses:

215

Ruby sortne trie pas sur place. (Avez-vous peut-être une formation Python?)

Ruby a sort!pour le tri sur place, mais il n'y a pas de variante sur place pour sort_byRuby 1.8. En pratique, vous pouvez faire:

sorted = sort_me.sort_by { |k| k["value"] }
puts sorted

À partir de Ruby 1.9+, .sort_by!est disponible pour le tri sur place:

sort_me.sort_by! { |k| k["value"]}
Stéphan Kochen
la source
28
En fait, Array#sort_by!est nouveau dans Ruby 1.9.2. Disponible aujourd'hui pour toute la version Ruby en demandant aussi mon backportsbijou :-)
Marc-André Lafortune
Salut, existe-t-il également un moyen de trier par ordre décroissant? Je pense que je pourrais vouloir y aller 3,2,1...
tekknolagi
2
Vous ne pouvez pas faire cela avec sort_by, mais utilisez sortou sort!et retournez simplement les opérandes: a.sort! {|x,y| y <=> x }( ruby-doc.org/core-1.9.3/Array.html#method-i-sort )
Stéphan Kochen
1
Ou:puts sorted = sort_me.sort_by{ |k,v| v }
Zaz
9
@tekknolagi: Ajoutez simplement .reverse.
Zaz
21

Selon @shteef mais implémenté avec la sort!variante comme suggéré:

sort_me.sort! { |x, y| x["value"] <=> y["value"] }
bjg
la source
7

Bien que Ruby n'ait pas de sort_byvariante sur place, vous pouvez faire:

sort_me = sort_me.sort_by { |k| k["value"] }

Array.sort_by! a été ajouté en 1.9.2

AG_
la source
1
Cette réponse "Array.sort_by! A été ajoutée dans la version 1.9.2" a fonctionné pour moi
web spider26
2

Vous pouvez utiliser sort_me.sort_by!{ |k| k["value"]}. Cela devrait fonctionner.

Mukesh Kumar Gupta
la source