Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtle difference between sort and sort_by

Tags:

sorting

ruby

This is not a trick question:

[1,2,3].sort_by { |x, y| x <=> y }
=> [1, 2, 3] 

[1,2,3].sort_by { |x, y| y <=> x }
=> [1, 2, 3] 

What's going on here? I would have expected the arrays to be opposite one another (as they are with sort and the same parameters).

like image 323
Chris B Avatar asked Jun 18 '13 22:06

Chris B


People also ask

How does sort_by work in Ruby?

sort_by works by creating what you can think of as an invisible hash. When called on an array, it calculates a set of numerical keys (known as “sort keys”), and assigns each element in the array to one of those sort keys. Then, the keys are sorted, and mapped back onto the original values.

How do you sort a hash in Ruby?

To sort a hash in Ruby without using custom algorithms, we will use two sorting methods: the sort and sort_by. Using the built-in methods, we can sort the values in a hash by various parameters.

How do you sort an array of arrays in Ruby?

You can use the sort method on an array, hash, or another Enumerable object & you'll get the default sorting behavior (sort based on <=> operator) You can use sort with a block, and two block arguments, to define how one object is different than another (block should return 1, 0, or -1)


2 Answers

[1, 3, 2].sort_by { |x| x }
=> [1, 2, 3] 

[1, 3, 2].sort_by { |x| -x }
=> [3, 2, 1] 

[1, 3, 2].sort
=> [1, 2, 3] 

[1, 3, 2].sort.reverse
=> [3, 2, 1] 

[1, 3, 2].sort { |x, y| x <=> y }
=> [1, 2, 3] 

[1, 3, 2].sort { |x, y| y <=> x }
=> [3, 2, 1] 
like image 23
Ian Kenney Avatar answered Oct 18 '22 22:10

Ian Kenney


#sort_by should just take one block parameter, an item from the array, and sorts based on the result of the block.

When passing it two block parameters, the second is set to nil and thus all block results are like 1 <=> nil which is nil so the order of the array is unchanged.

[1, 3, 2].sort_by { |x| x } # sorts using x <=> y
=> [1, 2, 3]

[1, 3, 2].sort_by { |x, y| x <=> y } # sorts using nil <=> nil
=> [1, 3, 2]
like image 159
robertjlooby Avatar answered Oct 18 '22 22:10

robertjlooby