这就是我现在正在做的工作。
这是我的代码(请随意批评它(。
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或去掉它。
你可以做的是首先将数组元素映射为数字,然后你就不必依赖于减少/注入
weight.split("").map(&:to_i).inject{|sum,n| sum+n}