【问题标题】:Is there an implicit keyword in this Ruby Array map code?此 Ruby 数组映射代码中是否有隐式关键字?
【发布时间】:2013-05-04 17:22:12
【问题描述】:

是否有一个关键字可以用来明确告诉 map 函数该特定迭代的结果应该是什么?

考虑:

a = [1,2,3,4,5]
a.map do |element|
  element.to_s
end

在上面的例子中 element.to_s 是每次迭代的结果。

在某些情况下,我不想依赖使用最后执行的行作为结果,我更愿意在代码中明确说明结果是什么。

例如,

a = [1,2,3,4,5]
a.map do |element|
  if some_condition
    element.to_s
  else
    element.to_f
  end
end

如果写成这样,我可能会更容易阅读:

a = [1,2,3,4,5]
a.map do |element|
  if some_condition
    result_is element.to_s
  else
    result_is element.to_f
  end
end

那么有什么关键字可以代替result_is吗?

return 将从调用函数返回,break 将提前停止迭代,所以这些都不是我想要的。

【问题讨论】:

    标签: ruby iteration block


    【解决方案1】:

    最后留在堆栈上的东西自动是调用块的结果。你是对的,return 在这里不会产生预期的效果,但忽略了另一种可能性:声明一个单独的函数来评估条目。

    例如,你的代码的修改:

    def function(element)
       if (some_condition)
         return element.to_s
       end
    
       element.to_f
    end
    
    a.map do |element|
      function(element)
    end
    

    调用该函数会产生名义上的开销,但在小型列表中这应该不是问题。如果这对性能非常敏感,那么您将需要努力做到这一点。

    【讨论】:

    • tap 只返回作为参数传入的任何对象,而不管块中发生了什么。我不确定这有什么用,因为它不允许产生不同的结果。
    【解决方案2】:

    是的,有,它叫做next。但是,在这种特殊情况下使用next不会提高可读性。相反,它会 a) 混淆读者 b) 给他的印象是该代码的作者不了解 Ruby。

    everything 是 Ruby 中的一个表达式(有 no 语句)并且每个表达式的计算结果都是该表达式中最后一个子表达式的值这一事实是基础 Ruby 知识。

    就像return 一样,next 只应在您想从块的中间“返回”时使用。通常,您只将其用作保护子句。

    【讨论】:

      【解决方案3】:

      map 的本质是将最后执行的行分配给数组。您的最后一个示例与以下示例非常相似,它遵循预期的行为:

      a = [1,2,3,4,5]
      a.map do |element|
        result = if some_condition
          element.to_s
        else
          element.to_f
        end
        result
      end
      

      【讨论】:

      • 如果可以直接返回if 表达式的结果,为什么要将if 表达式的结果分配给result 并返回result? :)
      【解决方案4】:

      不,ruby 中没有语言关键字可用于在迭代中执行其他代码之前确定映射到结果数组的结果。

      您可以分配一个变量,然后在执行其他代码时返回该变量:

      a.map do |element|
        result = some_condition ? element.to_s : element.to_f
      
        #do something else with element
      
        result
      end
      

      请记住,ruby 没有为此类代码提供关键字的原因是这些模式的可读性往往非常低。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-19
        • 2011-08-26
        • 2013-06-14
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        • 1970-01-01
        相关资源
        最近更新 更多