迭代时返回迭代对象和索引

fl0*_*00r 4 ruby

array = [1,2,3,{:name => "Peter"}, "hello"]
array.each do |element| # it can be "inject", "map" or other iterators
  # How to return object "array" and position of "element"
  # also next and priviouse "element"
end
Run Code Online (Sandbox Code Playgroud)

当然我可以返回索引array.index[element]但我正在寻找更自然的解决方案.就像proxy_owner在Rails协会中一样

Ruby 1.8.7

我要输出什么?我希望返回我迭代的对象(在我的情况下为数组),迭代次数(在each_with_index的情况下为索引)next和itei的属性元素.

作为输入我有一个数组和迭代器(每个,地图,注入等)

saw*_*awa 6

使用Enumerable#each_cons.以下是ruby1.8.7 rdoc的副本.它应该适用于ruby 1.8.7.


  • each_cons(n){...}
  • each_cons(n)的

迭代每个连续元素数组的给定块.如果没有给出块,则返回枚举器.


有了这个,你可以给一个数组:

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a

# => ["a", "b", "c"], ["b", "c", "d"], ["c", "d", "e"]]
Run Code Online (Sandbox Code Playgroud)

或做:

['a', 'b', 'c', 'd', 'e'].each_cons(3) {|previous, current, nekst|
    puts "#{previous} - #{current} - #{nekst}"
}

# => a - b - c
# => b - c - d
# => c - d - e
Run Code Online (Sandbox Code Playgroud)

如果你想要indice,

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a.each_with_index {|(previous, current, nekst), i|
    puts "#{i + 1}. #{previous} - #{current} - #{nekst}"
}

# => 1. a - b - c
# => 2. b - c - d
# => 3. c - d - e
Run Code Online (Sandbox Code Playgroud)

您可以将数组通常传递给其他枚举器,例如,使用inject:

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a.inject(''){|str, (previous, current, nekst)|
    str << previous+current+nekst
}

# => "abcbcdcde"
Run Code Online (Sandbox Code Playgroud)


saw*_*awa 5

在ruby1.8中,有each_with_index.

如果你想在其他迭代器上使用它,比如inject,map...,并且如果你使用的是ruby1.9,那么Enumerator#with_index你可以将方法附加到各种迭代器上.

枚举#with_index


the*_*Man 5

Ruby 的each_with_index功能可以轻松地重新创建:

ary = %w[zero one two three]
ary.zip((0 .. (ary.size - 1)).to_a).to_a # => [["zero", 0], ["one", 1], ["two", 2], ["three", 3]]

ary.zip((0 .. (ary.size - 1)).to_a).each do |a, i|
  puts "this element: #{a}"
  puts "previous element: #{ary[i - 1]}" if (i > 0)
  puts "next element: #{ary[i + 1]}" if (i < (ary.size - 1))
  puts
end
# >> this element: zero
# >> next element: one
# >> 
# >> this element: one
# >> previous element: zero
# >> next element: two
# >> 
# >> this element: two
# >> previous element: one
# >> next element: three
# >> 
# >> this element: three
# >> previous element: two
# >> 
Run Code Online (Sandbox Code Playgroud)

一旦知道当前对象的索引,您就可以查看正在迭代的数组并轻松获取上一个和下一个值。

所以,你可以这样做:

module Enumerable
  def my_each_with_index
    self.zip((0 .. (self.size - 1)).to_a).each do |a, i|
      yield a, i
    end
  end
end

ary.my_each_with_index { |a,i| puts "index: #{i} element: #{a}" }
# >> index: 0 element: zero
# >> index: 1 element: one
# >> index: 2 element: two
# >> index: 3 element: three
Run Code Online (Sandbox Code Playgroud)