Eloquent Ruby:构建迭代器,按顺序排列实际不存在的集合

时间:2013-07-28 03:39:01

标签: ruby

我正在读Russ Olsen的“Eloquent Ruby”。在下面的代码(Loc 3264)之后,他说:“请注意,我们从未真正构建所有单词对的四元素数组:我们只是动态生成对。”我不明白这里发生了什么。那话是什么?

class Document
    #Most of the class omitted...

    def each_word_pair  
        word_array = words
        index = 0
        while index < (word_array.size-1)
            yield word_array[index], word_array[index+1]
            index += 1
        end
    end
end

doc = Document.new('Donuts', '?', 'I love donuts mmmm donuts')
doc.each_word_pair{|first, second| puts "#{first} #{second}"}
#=> I love
#=> love donuts
#=> donuts mmmm
#=> mmmm donuts

1 个答案:

答案 0 :(得分:6)

  

那么什么是文字?

words是字符串'I love donuts mmmm donuts',它不是他所说的“所有单词对的四元素数组”。

  

“请注意,我们从未真正构建所有单词对的四元素数组:我们只是动态生成对。”我不明白这里发生了什么。

他指的是数组[["I", "love"], ["love", "donuts"], ["donuts", "mmmm"], ["mmmm", "donuts"]]each_word_pair方法中从不存在的事实。这是因为它创建了每个单独的对,然后yield将它们发送到调用块。因此它会生成第一对(["I", "love"]),yield s,然后为下一对生成。但each_word_pair本身从不包含所有四对。

例如,我们可以改为使用类似的方法:

def word_pairs
  word_array = words
  word_pairs = []

  index = 0
  while index < (word_array.size-1)
    word_pairs << [word_array[index], word_array[index+1]]
    index += 1
  end

  word_pairs
end

创建一个包含所有四对的数组并返回它。请注意我们如何构建一个额外的局部变量(word_pairs)来保存我们正在制作的数组,之前不需要它,因为它根本就没有存储。

请注意,each_word_pair是用2调用的Ruby core’s each_cons编写得有点糟糕的版本。