Ruby可枚举重置?

时间:2015-02-10 18:17:50

标签: ruby

我无法准确了解ruby可枚举的状态。 我知道一些python,所以我期待在我从一个可枚举中取出一个项目之后,它已经消失了,下一个项目将在我拿另一个项目时返回。 奇怪的是,当我使用next时会发生这种情况,但是当我使用take first之类的内容时却不会发生这种情况。 这是一个例子:

a = [1,2,3].to_enum
# => #<Enumerator: [1, 2, 3]:each>
a.take(2)
# => [1, 2]
a.next
# => 1
a.next
# => 2
a.take(2)
# => [1, 2]
a.next
# => 3
a.next
# StopIteration: iteration reached an end
#        from (irb):58:in `next'
#        from (irb):58
#        from /usr/bin/irb:12:in `<main>'
a.take(2)
# => [1, 2]

似乎可枚举在next次呼叫之间保持状态,但在每次take呼叫之前重置?

2 个答案:

答案 0 :(得分:2)

根据文档,Enumerable#take返回Enumerator中的前n个元素,而不是光标中的下n个元素。只有来自Enumerator的方法才会对该内部游标进行操作; Enumerable mix-in只是一组用于枚举哪些不一定共享游标的方法。

如果您愿意,可以实施Enumerator #take来做您期望的事情:

class Enumerator
  def take(n = 1)
    n.times.map { self.next }
  end
end

答案 1 :(得分:2)

这可能有点令人困惑,但重要的是要注意在Ruby中有Enumerator类和Enumerable模块。

Enumerator课程包括Enumerable(与大多数可枚举对象一样,例如ArrayHash等。

next方法作为Enumerator的一部分提供,它确实具有内部状态。您可以考虑Enumerator非常接近其他语言公开的Iterator概念。

实例化枚举器时,内部指针指向集合中的第一个项目。

2.1.5 :021 > a = [1,2,3].to_enum
 => #<Enumerator: [1, 2, 3]:each>
2.1.5 :022 > a.next
 => 1
2.1.5 :023 > a.next
 => 2

这不是枚举器的唯一目的(否则它可能被称为Iterator)。但是,这是记录的功能之一。

  

Enumerator也可以用作外部迭代器。例如,#next返回迭代器的下一个值,或者如果Enumerator在最后,则引发StopIteration。

e = [1,2,3].each   # returns an enumerator object.
puts e.next   # => 1
puts e.next   # => 2
puts e.next   # => 3
puts e.next   # raises StopIteration

但正如我之前所说,Enumerator课程包括Enumerable。这意味着Enumerator的每个实例都会公开旨在处理集合的Enumerable方法。在这种情况下,集合是Enumerator被包裹的集合。

take是一种通用Enumerable方法。它旨在从enum返回前N个元素。值得注意的是,enum指的是包含Enumerable的任何通用类,而不是Enumerator。因此,take(2)将返回集合的前两个元素,无论指针在Enumerator实例中的位置如何。

让我告诉你一个实际的例子。我可以创建自定义类,并实现Enumerable

class Example
  include Enumerable

  def initialize(array)
    @array = array
  end

  def each(*args, &block)
    @array.each(*args, &block)
  end
end

我可以混用Enumerable,只要我为each提供实现,我就会免费获得所有其他方法,包括take

e = Example.new([1, 2, 3])
 => #<Example:0x007fa9529be760 @array=[1, 2, 3]>
e.take(2)
 => [1, 2]

正如所料,take返回前2个元素。 take忽略了我实现的任何其他内容,与Enumerable完全相同,包括状态或指针。