2016-10-30 5 views
0

配列全体をどの位置からでも繰り返したいと思います。 Rubyでこれを簡単に達成する方法があるかどうかはわかりませんが、ArrayまたはEnumeratorドキュメントで例が見つかりませんでした。Ruby:配列全体をn番目の位置から反復処理します。

array = [0, 1, 2, 3, 4] 
array.each.starting_at(3) { |e| e } 
#=> [3, 4, 0, 1, 2] 

も:

array.each.starting_at_reverse(3) { |e| e } 
#=> [3, 2, 1, 0, 4] 

答えて

2

このためrotate方法を使用することができます。このメソッドは、各要素の位置をnで回転します。第二の方法のために回転させるためのパラメータがnの負のインデックスを見つけることによって導出することができます。だからあなたの例では、この

array.rotate(3).each {|e| e } 

array.reverse.rotate(1).each {|e| e} 

ノートのように行うことができます。したがって、このためには、インデックス3の要素は、長さ5のインデックス-2にあります。

+1

パーフェクト!学習経験ありがとう! – user3281384

+0

@ user3281384心配はいりません。良い質問! –

+0

'rotate'良い点。 'each {| e | e}は両方の例の要件に余計に見える。 –

0

あなたはuptodownto Fixnumかの方法でこれを行うことができます。

array = [0, 1, 2, 3, 4] 
last_index = array.size - 1 

3.upto last_index do |i| 
    puts array[i] 
end 
# => 3, 4 

last_index.downto 3 do |i| 
    puts array[i] 
end 
# => 4, 3 

PS。

require 'benchmark' 

array = Array.new(10000000) { rand(1...9) } 
last_index = array.size - 1 

Benchmark.bm do |x| 
    x.report 'upto' do 
    10000.upto last_index do |index| a = array[index] + 1; end 
    end 

    x.report 'downto' do 
    last_index.downto 10000 do |index| a = array[index] + 1; end 
    end 

    x.report 'rotate' do 
    array.rotate(10000).each {|e| a = e + 1 } 
    end 
end 

# RESULTS: 
# user  system  total  real 
# upto 0.680000 0.000000 0.680000 ( 0.681932) 
# downto 0.680000 0.000000 0.680000 ( 0.679752) 
# rotate 0.590000 0.040000 0.630000 ( 0.622901) 

しかし、メモリのベンチマークとして、配列インデックスによって反復少ないメモリ空腹、特に大きな配列サイズ上:

require 'memory_profiler' 

array = Array.new(10000000) { rand(1...9) } 
last_index = array.size - 1 

{ 
    upto: -> { 10000.upto last_index do |index| a = array[index] + 1; end }, 
    downto: -> { last_index.downto 10000 do |index| a = array[index] + 1; end }, 
    rotate: -> { array.rotate(10000).each {|e| a = e + 1 } }, 
    reverse_rotate: -> { array.reverse.rotate(10000).each {|e| a = e + 1 } } 
}.each { |desc, code| puts "#{desc.to_s} => #{MemoryProfiler.report(&code).total_allocated_memsize.to_s}" } 

# RESULTS (in bytes): 
# upto   => 0   # no additional memory allocation 
# downto   => 0   # no additional memory allocation 
# rotate   => 80000040 # implicitly copied array 1 time 
# reverse_rotate => 160000080 # implicitly copied array 2 times 
スピードのベンチマーク、回転速い

array.rotate(3).each {|e| puts e} 

ベンチマークと反復として

関連する問題