Reversing the Order of an Array in Ruby

reversing the order of an array in ruby

a = [12,16,5,9,11,5,4]
# => [12, 16, 5, 9, 11, 5, 4]
a.reverse
# => [4, 5, 11, 9, 5, 16, 12]

I'm not seeing what you're seeing.

Edit: Expanding on what Ben noticed, you may be reversing a string.

"12,16,5,9,11,5,4".reverse
# => "4,5,11,9,5,61,21"

If you have to reverse a string in that manner, you should do something like the following:

"12,16,5,9,11,5,4".split(",").reverse.join(",")
# => "4,5,11,9,5,16,12"

ruby** reverse array without using reverse method

Here's one way to handle this. This is not very efficient but works.

def reversal(array)
reversed = []
loop do
reversed << array.pop
break if array.empty?
end
reversed
end

Here is another implementation that does the same thing:

def reversal(array)
array.each_with_index.map do |value, index|
array[array.count-index-1]
end
end

How do you reverse order in ruby

You probably want #select and #reverse.

puts (1..200).select { |i| i % 3 == 0 }.reverse

Ruby sort array on condition in reverse order

The length is a number so you can simply negate it to reverse the order:

a.sort_by! { |s| -s.length }

If you're sorting on something that isn't easily negated then you can use sort! and manually reverse the comparison. For example, normally you'd do this:

# shortest to longest
a.sort! { |a,b| a.length <=> b.length }

but you can swap the order to reverse the sorting:

# longest to shortest
a.sort! { |a,b| b.length <=> a.length }

reverse order of Array in Ruby with index counter

Ruby has reversing an array built in:

@dates.reverse!

From http://ruby-doc.org/core-1.8.7/Array.html#method-i-reverse-21

How to change order of elements in array of arrays?

Various options (each version followed by short-hand sugar):

# Create a new array of swapped elements
my_array = my_array.map{ |a| a.reverse }
my_array = my_array.map(&:reverse)

# Mutate the existing array with swapped elements
my_array.map!{ |a| a.reverse }
my_array.map!(&:reverse)

# Mutate the elements in the existing array
my_array.each{ |a| a.reverse! }
my_array.each(&:reverse!)

The first option is the 'safest', insofar as no existing arrays are modified (in case you have other references to them that should not be changed).

The second option is roughly the same as the first, unless you had two references to my_array and wanted one of them unswapped.

The third option is the most 'destructive'; every reference to the pairwise elements will be changed. However, it's also the most memory-efficient, because no new arrays are created.

Sorting an array in reverse order

reverse just reverses the order of the array, and does not sort it:

irb> arr = [3,1,5]
=> [3, 1, 5]

irb> arr.sort
=> [1, 3, 5]
irb> arr.sort {|x,y| y<=>x}
=> [5, 3, 1]
irb> arr.reverse
=> [5, 1, 3]

But of course you can combine sort and reverse to sort in reverse order:

irb> arr.sort.reverse
=> [5, 3, 1]

How to sort an array in descending order in Ruby

It's always enlightening to do a benchmark on the various suggested answers. Here's what I found out:


#!/usr/bin/ruby

require 'benchmark'

ary = []
1000.times {
ary << {:bar => rand(1000)}
}

n = 500
Benchmark.bm(20) do |x|
x.report("sort") { n.times { ary.sort{ |a,b| b[:bar] <=> a[:bar] } } }
x.report("sort reverse") { n.times { ary.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
x.report("sort_by -a[:bar]") { n.times { ary.sort_by{ |a| -a[:bar] } } }
x.report("sort_by a[:bar]*-1") { n.times { ary.sort_by{ |a| a[:bar]*-1 } } }
x.report("sort_by.reverse!") { n.times { ary.sort_by{ |a| a[:bar] }.reverse } }
end

user system total real
sort 3.960000 0.010000 3.970000 ( 3.990886)
sort reverse 4.040000 0.000000 4.040000 ( 4.038849)
sort_by -a[:bar] 0.690000 0.000000 0.690000 ( 0.692080)
sort_by a[:bar]*-1 0.700000 0.000000 0.700000 ( 0.699735)
sort_by.reverse! 0.650000 0.000000 0.650000 ( 0.654447)

I think it's interesting that @Pablo's sort_by{...}.reverse! is fastest. Before running the test I thought it would be slower than "-a[:bar]" but negating the value turns out to take longer than it does to reverse the entire array in one pass. It's not much of a difference, but every little speed-up helps.


Please note that these results are different in Ruby 1.9

Here are results for Ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin10.8.0]:

                           user     system      total        real
sort 1.340000 0.010000 1.350000 ( 1.346331)
sort reverse 1.300000 0.000000 1.300000 ( 1.310446)
sort_by -a[:bar] 0.430000 0.000000 0.430000 ( 0.429606)
sort_by a[:bar]*-1 0.420000 0.000000 0.420000 ( 0.414383)
sort_by.reverse! 0.400000 0.000000 0.400000 ( 0.401275)

These are on an old MacBook Pro. Newer, or faster machines, will have lower values, but the relative differences will remain.


Here's a bit updated version on newer hardware and the 2.1.1 version of Ruby:

#!/usr/bin/ruby

require 'benchmark'

puts "Running Ruby #{RUBY_VERSION}"

ary = []
1000.times {
ary << {:bar => rand(1000)}
}

n = 500

puts "n=#{n}"
Benchmark.bm(20) do |x|
x.report("sort") { n.times { ary.dup.sort{ |a,b| b[:bar] <=> a[:bar] } } }
x.report("sort reverse") { n.times { ary.dup.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
x.report("sort_by -a[:bar]") { n.times { ary.dup.sort_by{ |a| -a[:bar] } } }
x.report("sort_by a[:bar]*-1") { n.times { ary.dup.sort_by{ |a| a[:bar]*-1 } } }
x.report("sort_by.reverse") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse } }
x.report("sort_by.reverse!") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse! } }
end

# >> Running Ruby 2.1.1
# >> n=500
# >> user system total real
# >> sort 0.670000 0.000000 0.670000 ( 0.667754)
# >> sort reverse 0.650000 0.000000 0.650000 ( 0.655582)
# >> sort_by -a[:bar] 0.260000 0.010000 0.270000 ( 0.255919)
# >> sort_by a[:bar]*-1 0.250000 0.000000 0.250000 ( 0.258924)
# >> sort_by.reverse 0.250000 0.000000 0.250000 ( 0.245179)
# >> sort_by.reverse! 0.240000 0.000000 0.240000 ( 0.242340)

New results running the above code using Ruby 2.2.1 on a more recent Macbook Pro. Again, the exact numbers aren't important, it's their relationships:

Running Ruby 2.2.1
n=500
user system total real
sort 0.650000 0.000000 0.650000 ( 0.653191)
sort reverse 0.650000 0.000000 0.650000 ( 0.648761)
sort_by -a[:bar] 0.240000 0.010000 0.250000 ( 0.245193)
sort_by a[:bar]*-1 0.240000 0.000000 0.240000 ( 0.240541)
sort_by.reverse 0.230000 0.000000 0.230000 ( 0.228571)
sort_by.reverse! 0.230000 0.000000 0.230000 ( 0.230040)

Updated for Ruby 2.7.1 on a Mid-2015 MacBook Pro:

Running Ruby 2.7.1
n=500
user system total real
sort 0.494707 0.003662 0.498369 ( 0.501064)
sort reverse 0.480181 0.005186 0.485367 ( 0.487972)
sort_by -a[:bar] 0.121521 0.003781 0.125302 ( 0.126557)
sort_by a[:bar]*-1 0.115097 0.003931 0.119028 ( 0.122991)
sort_by.reverse 0.110459 0.003414 0.113873 ( 0.114443)
sort_by.reverse! 0.108997 0.001631 0.110628 ( 0.111532)

...the reverse method doesn't actually return a reversed array - it returns an enumerator that just starts at the end and works backwards.

The source for Array#reverse is:

               static VALUE
rb_ary_reverse_m(VALUE ary)
{
long len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);

if (len > 0) {
const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}

do *p2-- = *p1++; while (--len > 0); is copying the pointers to the elements in reverse order if I remember my C correctly, so the array is reversed.

Printing array of multi-digit elements in reverse order in ruby

If you like one-liners:

gets.strip.split(' ').reverse.join(' ')

This will take the input 1 2 3 45 678 9 and convert it to "9 678 45 3 2 1"



Related Topics



Leave a reply



Submit