2014-10-10 61 views
2

我没有看到使用统计员。戴夫托马斯的书陈述如下:统计员超过集合的优势

枚举器允许您捕获作为一个对象的枚举的概念。这允许您将枚举存储在变量中,将它们作为参数传递,等等。

但我也可以分配数组到变量,传递数组作为参数等。事实上,我认为使用常规的迭代器集合像数组比使用枚举更简洁:

str = "quick brown fox" 
str.scan(/\w+/).each {|w| puts w } 
quick 
brown 
fox 

str = "quick brown fox" 
enum = str.to_enum(:scan, /\w+/) 
enum.each { |w| puts w } 
quick 
brown 
fox 

枚举版本需要一个额外的步骤,并产生相同的结果。何时使用迭代器对集合使用枚举更实用?

回答

3

使用枚举使一些事情可能阵列不允许。

枚举器可以代表被懒惰地评估的序列,这意味着代码来生成的元件直到需要该元件没有得到运行。

这意味着,一个枚举可代表无限序列。例如:

e = Enumerator.new { |y| s = 'a'; loop { y << s = s.succ } } 
e.first(5) # => ["b", "c", "d", "e", "f"] 

这个例子显示了一个无限序列,这意味着它必须懒洋洋地评估,因为您的计算机是有限的。但即使你没有使用无限序列,懒惰的评估对于节省CPU时间仍然非常有帮助。

而且,枚举器可以使用外部迭代器,它提供了你如何使用它的各种灵活性。 (见7stud的回答是一个例子。)

+0

你能提供一个例子吗? – JohnMerlino 2014-10-10 04:02:04

+0

@JohnMerino,'E = [1,2,3] .cycle p e.first(10)' – 7stud 2014-10-10 04:06:08

2

普查员也外部迭代器,它允许你在一次遍历两个数组:

e1 = [1, 2, 3].each 
e2 = ['a', 'b', 'c'].each 

loop do 
    num, ch = e1.next, e2.next 
    puts "#{num} -> #{ch}" 
end 

--output:-- 
1 -> a 
2 -> b 
3 -> c 

当枚举用完的项目,它提出了一个StopIteration异常,并且loop()自动捕获该异常并终止。

+0

你正在做这里的事情可能与阵列和增加的索引整数来实现的,但一个枚举允许我们写得更简洁。 – 2014-10-10 04:12:26

+0

哇!所以这是我发现使用'loop'而不是'while'的第一个原因! – 2014-10-10 04:13:25