我是Ruby的新手,正在尝试理解Ruby Blocks。
有没有办法在下面的代码块中包含i
,或者像下面这样在代码块之外声明它?
i = 0
nums.each_with_index do |num, j|
if num != 0
nums[i], nums[j] = num, nums[i]
i += 1
end
end
我尝试将i
初始化为一个块变量,但它不起作用。
nums.each_with_index do |num, j; i = 0|
2条答案
按热度按时间yhxst69z1#
有一个技巧可以让
i
本地化到块,而不是在迭代之外“泄漏”:这个人为的例子定义了您的
i
(从42
开始只是为了举例,但您可能更喜欢0
)。并迭代一个包含索引的项数组,然后求和。each_with_index
将返回一个Enumerator,您可以在其上调用inject
(也称为reduce
),它接受一个初始值和一个块,并传递称为accumulator
的值(在本例中基本上是i
,可以使用此变量来累积结果)作为此块的第一个参数,你可以用它把一个集合中的项转换成一个值。我不认为有任何其他的方法来做到这一点。在一个块内部定义的变量只对一个块的那个 * 调用 * 可见(所以对于每个迭代,整个块都被执行,所以如果你执行
i = 0
,那么每个项目都是0
。我相信,如果您不想在块外声明变量,我对
inject
的建议将是一个惯用的解决方案。所以,你的例子看起来像这样(请注意,我不能测试它,因为你的例子是不完整的,即。你不指定
nums
是什么)fiei3ece2#
您希望在修改
nums
后,保持i
的值不被窥探。一个简单(但荒谬)的解决方案是将代码封装在一个只执行一次的块中。
您应该简单地将代码封装在一个方法中,而不是采用扭曲的方法来隐藏
i
的值。