【问题标题】:What are the differences between "each", "foreach", "collect" and "map"? [duplicate]“each”、“foreach”、“collect”和“map”有什么区别? [复制]
【发布时间】:2013-03-28 11:38:20
【问题描述】:

似乎有很多方法可以在 Ruby 中循环遍历 Enumerable。 eachforeachcollectmap或其他类似方法有什么区别吗?

或者有什么理由我不应该在某些情况下使用某些方法?

【问题讨论】:

    标签: ruby loops enums iterator iteration


    【解决方案1】:

    collect/map 是等价的。它们与each 的不同之处在于each 只为每个元素执行块,而collect/map 返回一个数组,其中包含为每个元素调用块的结果。另一种说法可能是,each 应该对每个元素一些事情,而 map 应该转换每个元素(将它映射到其他东西上) )。

    您可以在任何使用each 的地方使用collectmap,并且您的代码仍然可以工作。但它的效率可能会稍低一些,因为它将结果收集在一个数组中,除非您的 Ruby 实现意识到它不必费心创建一个数组,因为它从未使用过。

    使用each 而不是mapcollect 的另一个原因是帮助任何阅读您的代码的人。如果我看到each,那么我可以说好吧,我们将使用数据的每个元素来做一些事情。如果我看到map,那么我希望看到基于旧数据的重新映射创建新数据。

    关于 mapcollect 我会说这是一个偏好问题,但你应该选择一个并坚持下去以保持一致性。

    【讨论】:

    • "each 应该对每个元素做一些事情,而map 应该对每个元素进行转换" 转换不也是一种做事的形式吗?区别不在于做什么,而在于返回什么。
    【解决方案2】:

    使用pryRubinus(更容易阅读ruby代码)自己看看

    $ pry
    [1] pry(main)> cd Enumerable
    [2] pry(Enumerable):1> show-method collect
    
    From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
    Owner: Enumerable
    Visibility: public
    Number of lines: 9
    
    def collect
      if block_given?
        ary = []
        each { |o| ary << yield(o) }
        ary
      else
        to_a
      end
    end
    
    [3] pry(Enumerable):1> show-method map
    
    From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
    Owner: Enumerable
    Visibility: public
    Number of lines: 9
    
    def collect
      if block_given?
        ary = []
        each { |o| ary << yield(o) }
        ary
      else
        to_a
      end
    end
    [4] pry(Enumerable):1>
    

    所以不适合这两个。

    mapcollect 迭代一个集合。对于每个对象,它执行你的块然后收集结果。 each 方法不收集结果

    【讨论】:

      【解决方案3】:

      Array#collect(和Array#map)根据块中传递的代码返回一个新数组。 Array#each 对数组的每个元素执行一个操作(由块定义)。

      我会像这样使用collect

      array = [1, 2, 3]
      array2 = array.collect {|val| val + 1}
      
      array.inspect # => "[1, 2, 3]"
      array2.inspect # => "[2, 3, 4]"
      

      each 这样:

      array = [1, 2, 3]
      array.each {|val| puts val + 1 }
      # >> 2
      # >> 3
      # >> 4
      array.inspect # => "[1, 2, 3]"
      

      【讨论】:

        猜你喜欢
        • 2012-03-14
        • 1970-01-01
        • 2016-12-19
        • 2016-06-11
        • 2015-05-19
        • 2016-07-20
        • 1970-01-01
        • 2011-11-12
        • 1970-01-01
        相关资源
        最近更新 更多