【问题标题】:Inplace enumeration就地枚举
【发布时间】:2013-05-02 11:49:19
【问题描述】:

我正在使用 ruby​​ 1.8.7 和 ruby​​ on rails 3.x 。我有很多这样的台词

lines = lines.map {|e| e.strip}
lines = lines.map {|e| e.upcase}
lines = lines.map {|e| sanitize_element(e)}

除了每次都为行分配新值之外,还有更好的方法来处理这个问题。我知道我能做到

lines = lines.map {|e| sanitize_element(e.strip.upcase) }

但这不是这个问题的重点。主要是寻找是否有一种方法可以处理上述情况,而无需每次都为行赋值。

基本上我正在寻找像这样优雅的解决方案,但我知道 Enumerable 中没有 map!

lines.map! {|e| e.strip}

只是确保我没有错过 ruby​​ 功能。

【问题讨论】:

    标签: ruby enumerable


    【解决方案1】:

    是的,通过使用Array#map!

    lines.map! { |e| e.strip }
    lines.map! { |e| e.upcase}
    # ...
    

    通常,像map 这样的不可变方法会与像map! 这样的危险方法配对,这会导致接收器被修改。我建议不要使用这些,因为好的、函数式可枚举编程的一半是为了获得不变性的好处(引用透明等)。但如果你要对每个枚举重新赋值,你不妨使用map!

    【讨论】:

    【解决方案2】:

    如果我正确理解你的问题,你可以写

    lines = lines.map {|e| e.strip}.map {|e| e.upcase}.map {|e| sanitize_element(e)}
    

    以流利的方式。这是你的意思吗?

    【讨论】:

      【解决方案3】:

      如果sanitize_element! 存在,你可以试试这个方法:

      lines.map! do |e|
        e.strip
        e.upcase
        e.sanitize_element
      end
      

      我认为它看起来更清晰。

      【讨论】:

        【解决方案4】:

        出于兴趣,请注意您可以不理会数组并专注于修改字符串本身。像这样:

        lines.each do |e|
          e.strip!
          e.upcase!
          e.replace(e.sanitize_element)
        end
        

        在随机数据的快速基准测试中,它的运行时间大约是多-map! 版本的 2/3,尽管显然您希望在实际数据和操作上验证这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-09
          • 2021-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多