Ruby:each_slice,map,inject

时间:2015-01-20 03:54:22

标签: python ruby

我试图将这些Ruby代码翻译成Python,但我无法理解它。我理解各个部分,但我是Ruby的新手,我觉得它们如何融合在一起让我感到困惑。

#input: 16 bit array
hexes = input.each_slice(4).map.inject([]) { |sum, s| sum << s.join.to_i(2)}

如果有人能帮我解读这个,我会非常感激! 谢谢

1 个答案:

答案 0 :(得分:2)

您可以通过在交互式Ruby提示符(irb)中键入每个步骤来轻松尝试此操作。

我们说input是:

["1", "0", "0", "1", 
 "0", "1", "0", "1", 
 "1", "0", "1", "0", 
 "0", "1", "1", "0"]

each_slice(4)将其分解为:

[["1", "0", "0", "1"], 
 ["0", "1", "0", "1"], 
 ["1", "0", "1", "0"], 
 ["0", "1", "1", "0"]]

在这种情况下,map是不必要的,什么都不做。

injectreduce相同。你给它一个初始值,然后用它和列表的第一项调用块,然后调用该调用的结果和列表中的下一项等等。

所以它被调用:

[[], ["1", "0", "0", "1"]]
[[9], ["0", "1", "0", "1"]]
[[9, 5], ["1", "0", "1", "0"]]
[[9, 5, 10], ["0", "1", "1", "0"]]

最后返回[9, 5, 10, 6]

在Python中,最接近的等价物将非常非Pythonic:

reduce(
    (lambda sum, s: (sum.append(int(''.join(s), 2)) or sum))
    (input[i * 4:(i + 1) * 4] for i in range(4)),
    [])

所以你可以这样做:

slices = (input[i * 4:(i + 1) * 4] for i in range(4))
sum = [int(''.join(s), 2) for s in slices]

Ruby中哪个更好:

input.each_slice(4).map { |s| s.join.to_i(2) }