我有一个类Test
:
class Test
attr_accessor :data
def initialize
@data = [0, 1, 2, 3]
end
def map
@data.map!{|i| i = yield i }
end
end
我试着这样使用它:
a = Test.new
a.map{|i|
if(i==2)
i+=1
break i #<--- -This line is the focus
else
1
end
}
puts a.data
我期望的输出是[1, 1, 3, 3]
。结果是[1, 1, 2, 3]
。map
中的块的最后一次迭代没有返回修改后的i
。
将break i
替换为next i
。这正如我预期的那样执行,并产生输出[1, 1, 3, 1]
。
如何修改这段代码(或者,最好是我在第二个代码片段中指出的那一行),以便得到输出[1, 1, 3, 3]
?换句话说,我怎样才能完成代码块,但将最后一个值传递回map
?有没有一种简洁易读的方法来做到这一点(除了,比如说,切换一个布尔标志break_now
)?
3条答案
按热度按时间r9f1avp51#
我假设你问的是如何离开一个块并利用最后计算的值,而不是如何计算一组特定的数字;对于后者,可能有一个聪明的俏皮话。
不如这样:
另外一个想法-
#map
是Ruby中一个重要的方法,有一个特定的接口。在您的示例中,您修改了Test
中的字段,从而违反了接口。因此,我使用了#modify
这个名字。afdcj2ne2#
一般来说,您可以通过修改产生的值来避免这种情况。例如,如果你的数组由String而不是Fixnums组成:
您的示例的问题是this:
Fixnum对象具有立即值。这意味着当它们作为参数赋值或传递时,传递的是实际的对象,而不是对该对象的引用。赋值不会为Fixnum对象设置别名。对于任何给定的整数值,实际上只有一个Fixnum对象示例…
固定数不能就地改变,所以下面代码块中的表达式
i += 1
不会影响上面代码块中i
的值。这就是为什么在您的示例中得到2
,而在我的示例中得到d
。t2a7ltrp3#
你必须这样做:
当你使用map函数时,你不会改变'a'变量,如果你想改变'a'变量,请这样做:
'i'的新值是块返回的值,所以不要这样做:
因为如果你这样做:
结果将是: