4

日付を含む配列があります。

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)>]

この配列のソート順が昇順か降順かを確認するにはどうすればよいですか?

4

4 に答える 4

11

2 つの隣接する各要素の最初の要素が 2 番目の要素より小さいか等しい場合、配列は昇順です。

def ascending? arr
  arr.each_cons(2).all?{|left, right| left <= right}
end

別の方法として (よりきれいですが、残念ながら遅くなります)、配列をそれ自体のソート済みバージョンと比較できます。

def ascending? arr
  arr == arr.sort
end
于 2012-10-15T16:54:42.267 に答える
6

処理速度のベンチマーク結果は次のとおりです。

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

テスト結果:

                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)

2020年の結果は次の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)
于 2012-10-15T18:33:04.440 に答える
0

私はreduceより速くなると思いますeach_cons

def ascending? arr
  arr.reduce{ |e1,e2| e1 <= e2 ? e2 : (return false) }; true
end
于 2012-10-15T17:10:15.553 に答える