viernes, 11 de enero de 2013

Ordenar Arrays en Ruby

Para ordenar un Array en Ruby, hay varios métodos.

Si tenemos un array normal, de enteros, por ejemplo:

Con el método sort se realiza el orden por defecto:

[1,2,56,8,6, 12].sort
 => [1, 2, 6, 8, 12, 56]

Si queremos otro orden, hay que incluir un bloque a la llamada. Por ejemplo, primero los impares:

 [1, 5, 7, 2, 56, 8, 3, 6, 12].sort{|x,y| y%2 <=> x%2}
 => [1, 5, 7, 3, 56, 8, 2, 6, 12] 


En este caso, salen primero los impares y luego los pares. Pongamos que queremos hacer esto, pero además, que salgan los números ordenados. Es decir, primero por par/impar, y luego por tamaño. Para ordenar por varios campos:

[1, 5, 7, 2, 56, 8, 3, 6, 12].sort{|x,y| [x%2, x] <=> [y%2, y]}
 => [2, 6, 8, 12, 56, 1, 3, 5, 7] 

En el caso de que en lugar de un array normal como el anterior, tuviéramos un array de objetos, de hash o de cualquier tipo de dato, la operación es similar:

[{:a=>1, :b=>"a"}, {:a=>11, :b=>"f"}, {:a=>34, :b=>"ah"}, {:a=>154, :b=>"dfg"}, {:a=>323, :b=>"tre"}, {:a=>16, :b=>"mh"}].sort{|x,y| x[:a] <=> y[:a]}
 => [{:a=>1, :b=>"a"}, {:a=>11, :b=>"f"}, {:a=>16, :b=>"mh"}, {:a=>34, :b=>"ah"}, {:a=>154, :b=>"dfg"}, {:a=>323, :b=>"tre"}] 


De la misma manera, con varios campos:

 [{:a=>1, :b=>"a"}, {:a=>11, :b=>"f"}, {:a=>34, :b=>"ah"}, {:a=>154, :b=>"dfg"}, {:a=>323, :b=>"tre"}, {:a=>16, :b=>"mh"}].sort{|x,y| [y[:b], x[:a]] <=> [x[:b], y[:a]]}
 => [{:a=>323, :b=>"tre"}, {:a=>16, :b=>"mh"}, {:a=>11, :b=>"f"}, {:a=>154, :b=>"dfg"}, {:a=>34, :b=>"ah"}, {:a=>1, :b=>"a"}]