【问题标题】:Differences between [1,2,3].to_enum and [1,2,3].enum_for in RubyRuby 中 [1,2,3].to_enum 和 [1,2,3].enum_for 的区别
【发布时间】:2014-07-14 01:32:40
【问题描述】:

在 Ruby 中,我试图了解 to_enumenum_for 方法之间的关系。在我提出问题之前,我已经提供了一些示例代码和两个示例来帮助了解上下文。

示例代码:

# replicates group_by method on Array class
class Array
  def group_by2(&input_block)
    return self.enum_for(:group_by2) unless block_given?
    hash  = Hash.new {|h, k| h[k] = [] }
    self.each { |e| hash[ input_block.call(e) ] << e }
    hash
  end
end

示例#1:

irb (main)> puts [1,2,3].group_by2.inspect
=> #<Enumerator: [1, 2, 3]:group_by2> 

在示例 #1 中:在数组 [1,2,3] 上调用 group_by,而不传入块,返回使用命令 self.enum_for(:group_by_2) 生成的枚举器。

示例 #2

irb (main)> puts [1,2,3].to_enum.inspect
=> #<Enumerator: [1, 2, 3]:each> 

在示例 #2 中,枚举数是通过在数组 [1,2,3] 上调用 to_enum 方法生成的

问题:

在示例 1 和 2 中生成的枚举器是否以任何方式表现不同?我可以从检查的输出中看到它们显示的标签略有不同,但我可以发现枚举器的行为有任何差异。

# Output for example #1
#<Enumerator: [1, 2, 3]:each> # label reads ":each"

# Output for example #2
#<Enumerator: [1, 2, 3]:group_by2> # label reads ":group_by2"

【问题讨论】:

    标签: ruby enumeration enumerable


    【解决方案1】:
    p [1, 2, 3].to_enum
    p [1, 2, 3].enum_for
    
    --output:--
    
    #<Enumerator: [1, 2, 3]:each>
    #<Enumerator: [1, 2, 3]:each>
    

    来自文档:

    to_enum

    创建一个新的枚举器,它将通过调用方法来枚举 obj,如果有的话,传递 args。

    ...

    enum_for

    创建一个新的枚举器,它将通过调用方法来枚举 obj,如果有的话,传递 args。

    ruby 是一种语言,其方法名称通常是同义词。

    后续问题:

    命令 [1,2,3].to_enum(:foo) 中的符号是否有作用, 除了在输出中用 :foo 替换 :each 吗?

    是的。默认情况下,ruby 将枚举器连接到接收器的 each() 方法。有些类没有each() 方法,例如String:

    str = "hello\world"
    e = str.to_enum
    puts e.next
    
    --output:--
    1.rb:3:in `next': undefined method `each' for "helloworld":String (NoMethodError)
        from 1.rb:3:in `<main>
    

    to_enum() 允许您指定希望枚举器使用的方法:

    str = "hello\nworld"
    e = str.to_enum(:each_line)
    puts e.next
    
    --output:--
    hello
    

    现在,假设您有数组[1, 2, 3],并且您想为您的数组创建一个枚举器。数组有一个 each() 方法,但不是用 each() 创建一个枚举器,它将返回数组中的每个元素,然后结束;你想创建一个枚举器,一旦到达数组的末尾就从数组的开头重新开始?

    e = [1, 2, 3].to_enum(:cycle)
    
    10.times do
      puts e.next()
    end
    
    --output:--
    1
    2
    3
    1
    2
    3
    1
    2
    3
    1
    

    【讨论】:

    • @ 7stud 谢谢。只是想确保我没有遗漏什么。
    • @amorphid, ruby​​ 文档曾经很擅长说,“这个方法是方法 A 的同义词。参见方法 A 的描述。”我宁愿看到那个推荐而不是重复的描述。
    • 我刚刚重读了您的示例,刚刚意识到也可以执行[1,2,3].to_enum(:foo),它返回#&lt;Enumerator: [1, 2, 3]:foo&gt;。如果我意识到这一点,我的问题只是 => 命令[1,2,3].to_enum(:foo) 中的符号是否有目的,而不是在输出中用:foo 替换:eachdocs for the Enumerator class 对此只字不提,至少我看不到。
    • @amorphid,我编辑了我的帖子来回答你的后续问题。
    • 谢谢。这正是我一直在寻找的答案!我花了一点时间才弄清楚如何提出这个问题:)
    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 2018-06-24
    • 2014-07-13
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    相关资源
    最近更新 更多