首页 > 解决方案 > 这 2 行代码实际上是做什么的?

问题描述

我不了解 Ruby,但我需要了解如何在下面几行中操作输入值。

我认为输入被转换为其字符值的总和,但第二行令人困惑;它是采用总和的最终值并执行按位运算还是每次迭代?您能否简单解释一下所遵循的步骤?

先感谢您!

input.to_s.each_char.inject(0) do |sum, ch|
    (sum << 8) ^ (ch.ord) ^ (sum >> 4)

标签: ruby

解决方案


inject与 reduce 相同,在许多其他语言中与 reduce 类似。

有许多不同的方式来调用它,但问题中显示的方式是这样的:

inject(initial) { |memo, obj| block } → obj

如果您指定一个块,那么对于枚举中的每个元素,该块都会传递一个累加器值(备忘录)和元素。如果你指定了一个符号,那么集合中的每个元素都将被传递给 memo 的命名方法。无论哪种情况,结果都会成为 memo 的新值。在迭代结束时,memo 的最终值就是方法的返回值。

如果没有显式指定 memo 的初始值,则 collection 的第一个元素用作 memo 的初始值。

所以在你的情况下:

input.to_s.each_char.inject(0) do |sum, ch|
    (sum << 8) ^ (ch.ord) ^ (sum >> 4)
end

sum 的初始值为 0,用于第一次迭代,但对于每个后续迭代,块的结果用于下一次迭代的 sum。

例如,以下应该在不使用注入/减少的情况下产生相同的值。

sum = 0
input.to_s.each_char do |ch|
    sum = (sum << 8) ^ (ch.ord) ^ (sum >> 4)
end

推荐阅读