I have an array which contains dates.
dates = [#<DateTime: 2002-07-01T00:00:00+00:00 ((2452457j,0s,0n),+0s,2299161j)>, #<DateTime: 2003-10-31T00:00:00+00:00 ((2452944j,0s,0n),+0s,2299161j)>, #<DateTime: 2003-12-01T00:00:00+00:00 ((2452975j,0s,0n),+0s,2299161j)>, #<DateTime: 2004-03-01T00:00:00+00:00 ((2453066j,0s,0n),+0s,2299161j)>, #<DateTime: 2004-03-01T00:00:00+00:00 ((2453066j,0s,0n),+0s,2299161j)>]
How can I check the sort order of this array if its ascending or descending?
An array is ascending if the first of each two adjacent elements is less or equal than the second:
def ascending? arr
arr.each_cons(2).all?{|left, right| left <= right}
end
alternatively (prettier but unfortunately slower), you can compare the array with sorted version of itself:
def ascending? arr
arr == arr.sort
end
Here's some benchmark results for processing speed:
require 'benchmark'
require 'date'
ary = (DateTime.parse('2002-07-01T00:00:00+00:00') .. DateTime.parse('2004-03-01T00:00:00+00:00')).to_a
def ascending1? arr
arr.reduce{ |e1,e2| e1 <= e2 ? e2 : (return false) }; true
end
def ascending2? arr
arr.each_cons(2).all?{|i,j| i <= j}
end
def ascending3? arr
arr == arr.sort
end
n = 10_000
Benchmark.bm(9) do |b|
b.report('reduce') { n.times{ ascending1?(ary) } }
b.report('each_cons') { n.times{ ascending2?(ary) } }
b.report('sort') { n.times{ ascending3?(ary) } }
end
With the test results:
user system total real
reduce 1.380000 0.000000 1.380000 ( 1.381107)
each_cons 2.250000 0.000000 2.250000 ( 2.243958)
sort 0.670000 0.000000 0.670000 ( 0.675025)
Here's some 2020 results with ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
:
user system total real
reduce 0.765766 0.000939 0.766705 ( 0.767853)
each_cons 1.220724 0.001394 1.222118 ( 1.223502)
sort 0.693166 0.009011 0.702177 ( 0.702492)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With