为什么当我显式转换为int时,我的代码会输入一个字符串,只用于一个特定的输出



这就是我现在正在做的工作。

这是我的代码(请随意批评它(。

def order_weight(weights)
    weightslist = weights.split(" ")
    def convert(weight)
      weight.split("").reduce{|sum,n| sum.to_i + n.to_i}
    end
   weightsconv = weightslist.map {|weight| convert(weight)}
   weightslist.sort_by{|a| [weightsconv[weightslist.index(a)],a]}.join(" ")
end

这适用于所有,除了以下输入字符串:order_weight("3 16 9 38 95 1131268 49455 347464 59544965313 496636983114762 85246814996697")

在这种情况下(通过打印(,我看到weightsconv中的前3个条目被损坏为"3"、"7"、"9"。其他一切都保持不变。这通过在第7行的末尾添加CCD_ 2来解决。我不明白为什么这是必要的,因为我已经在前一个块中转换了。这个一个输入内部出了什么问题?这是Ruby错误吗?

不,这是您的错误。

来自Enumerable#reduce文档:

如果没有为备忘录显式指定初始值,则集合的第一个元素将用作备注的初始值。

这可能就是您编写sum.to_i的原因,因为在您的情况下,sum最初是一个字符串。此外,如果集合只有一个元素(如["3"](,则无需调用块,因为正如文档所说,返回值是第一个元素(即"3"(。您的代码可以通过显式设置初始值(为0(来修复:

a = ["3"]
i = a.reduce { |sum, n| puts 'called'; sum + n.to_i } # no output
p i # => "3"
i = a.reduce(0) { |sum, n| puts 'called'; sum + n.to_i } # => called
p i # => 3

如果您希望对代码进行复查,请尝试代码复查堆栈交换。最大的代码气味是在另一个方法中定义一个方法。请使用lambda或去掉它。

如果reduce/injecte只包含一个元素,那么它将从可枚举对象返回一个元素

你可以做的是首先将数组元素映射为数字,然后你就不必依赖于减少/注入

weight.split("").map(&:to_i).inject{|sum,n| sum+n}

相关内容

最新更新