Ruby 中迭代元素和下一个元素的最简单方法,"the next element"上次迭代时为 nil?



我想遍历一个像[:foo, :bar, :baz]这样的数组。

在每次迭代中,我想要项目下一个项目。在最后一次迭代中,"下一项"应该是nil

所以我想依次生成:foo, :bar,然后是:bar, :baz,最后是:baz, nil

我可以想到一些实现这一目标的方法:

  • my_list.zip(my_list.from(1)) { |item, next_item| … }
  • my_list.each.with_index(1) { |item, i| next_item = my_list[i] }
  • [*my_list, nil].each_cons(2) { |item, next_item| … }

但我觉得我可能错过了一些更简单的方法。我是吗?

如果你的Array中只有三个非nil元素,并且每次都想从#each_cons中获取两个元素,那么只需添加一个nil,然后就可以结束了。

%i[foo bar baz].push(nil).each_cons(2).map { [_1, _2] }
#=> [[:foo, :bar], [:bar, :baz], [:baz, nil]]

或者,您可以根据当前或后续索引号引用命名数组的每个索引元素,因为对数组边界之外的元素的任何引用都将为nil。例如:

array = %i[foo bar baz]
array.each_index.map { [array[_1], array[_1.succ]] }
#=> [[:foo, :bar], [:bar, :baz], [:baz, nil]]

无论哪种情况,如果你想返回数组对象的数组,你都需要#map或其他机制。如果你想做其他事情,比如yield,你也可以这样做。

注意,如果要使用可变数量的Array元素,或者更改#each_cons项的数量,则需要使用不同的方法。如果是这种情况,请随意打开一个新的或相关的问题。