Ok, say I have an array like so [[z,1], [d,3], [e,2]], how can I sort this array by the second element of each constituent array? So that my array would look like the following? [[z,1], [e,2], [d,3]]?
Asked
Active
Viewed 2.2k times
26
-
2Note that this is really an array of arrays, not a 2-dimensional array. – Phrogz Aug 11 '11 at 23:25
-
possible duplicate of [Sort a collection of objects by number (highest first) then by letter (alphabetical)](http://stackoverflow.com/questions/2232470/sort-a-collection-of-objects-by-number-highest-first-then-by-letter-alphabetic) – Andrew Grimm Aug 11 '11 at 23:32
2 Answers
46
arr = [[:z,1], [:d,3], [:e,2]]
arr.sort {|a,b| a[1] <=> b[1]}
# => [[:z, 1], [:e, 2], [:d, 3]]
Or as user @Phrogz points out, if the inner arrays have exactly two elements each:
arr.sort_by{|x,y|y} # => [[:z, 1], [:e, 2], [:d, 3]]
arr.sort_by(&:last) # => [[:z, 1], [:e, 2], [:d, 3]]

maerics
- 151,642
- 46
- 269
- 291
-
14Or more simply: `arr.sort_by{|s,n| n }` or even `arr.sort_by(&:last)` (in Ruby 1.9). – Phrogz Aug 11 '11 at 23:24
-
@Phrogz Prefer `sort` because in ruby 2.4 (since 2.0 in fact or even before) `sort_by` doesn't exist but only `sort_by!` and the [doc](https://ruby-doc.org/core-2.4.0/Array.html#method-i-sort_by-21) says that: _The result is not guaranteed as stable. When two keys are equal, the order of the corresponding elements is unpredictable._ So in order to use `sort_by!` you must have uniq keys. So @maerics please edit your post to say that or remove `sort_by`. – noraj Jun 01 '17 at 16:10
-
@noraj note that arrays are [`Enumerable#sort_by`](http://ruby-doc.org/core-1.8.7/Enumerable.html#method-i-sort_by) since at least v1.8.7 and stability was not requested in the question. – maerics Jun 01 '17 at 16:22
-
what about sorting by second column and then any ties would be sorted by the first column? – kraftydevil Jun 17 '20 at 12:50
2
As user maerics answer it provides Ascending sorting.This answer is very useful for me thanks. For Descending sorting i use -
arr = [[:z,1], [:d,3], [:e,2]]
arr.sort {|a,b| a[1] <=> b[1]}.reverse
#=> [[:d, 3], [:e, 2], [:z, 1]]

Sandip Karanjekar
- 850
- 1
- 6
- 23
-
1You can save the "reverse" call by simply doing `arr.sort{|a,b|| b[1] <=> a[1]}` (note the reverse order of the operands of the comparison operator). – maerics Mar 07 '13 at 05:36
-
1you have a typo in your code, the correct code is `arr.sort{|a,b| b[1] <=> a[1]}`. you have inserted a pipe character too much – Fred Feb 09 '15 at 11:57