我找到了一个问题:Nested Loops Ruby并解决了它,但解决方案看起来很难看(虽然有效):
puts (1..10).map { |i| (i..10).step(i).inject(0) { |memo, obj| memo = memo | 2**(obj-1) } }.inject(0) { |memo, obj| memo = memo ^ obj}
重写为多行,但保持花括号:
puts (1..10).map { |i|
(i..10).step(i).inject(0) { |memo, obj|
memo = memo | 2**(obj-1)
}
}.inject { |memo, obj|
memo = memo ^ obj
}
我尝试将其重写为多行do-end块以使其更具可读性(了解{}
和do-end
之间的优先级差异)但是我收到错误(我刚刚更改了最后一个)括号):
puts (1..10).map { |i|
(i..10).step(i).inject(0) { |memo, obj|
memo = memo | 2**(obj-1)
}
}.inject do |memo, obj|
memo = memo ^ obj
end.to_s(2)
../../bitflipping.rb:5:in 'each': no block given (LocalJumpError) from ../../bitflipping.rb:5:in 'inject' from ../../bitflipping.rb:5:in ''
是否可以使用do-end
重写此内容?我认为存在一个优先级问题,我如何重新组合它们,例如inject
在最后得到正确的块?
答案 0 :(得分:0)
尝试将它变成一种方法,也许吧?虽然sawa说,map{|x| x}
没有做任何事情
def my_method
first_step = (1..10).map do |i|
(i..10).step(i).map { |x| x}.inject(0) { |memo, obj| memo = memo | 2**(obj-1) }
end
second_step = first_step.inject { |memo, obj| memo = memo ^ obj}.to_s(2)
return second_step
end
puts my_method
答案 1 :(得分:0)
触发问题的句法结构是没有括号的puts
。
您可以通过重构代码来解决问题,以便首先将结果分配给变量(例如result
),然后再执行puts result
。
替代解决方案是将整个表达式包装在括号中。
这里是对场景的精简再现:
# OK, because assignment has lower precedence than do/end
result = (1..10).inject do |memo, obj|
memo + obj
end
puts result
# OK because the outer parentheses resolves the ambiguity
puts(
(1..10).inject do |memo, obj|
memo + obj
end
)
# ERROR: no block given
puts (1..10).inject do |memo, obj|
memo + obj
end
发生错误是因为do
/ end
块的优先级低于方法调用(没有括号)。
ERROR案例相当于:
puts( (1..10).inject ) do |memo, obj|
memo + obj
end
...换句话说,您将该块传递给puts
而不是inject
。并且inject
(至少在这种情况下)失败,因为它需要一个块。