在 Ruby 中,我如何在迭代数组时修改它?

94

我刚开始学习Ruby,如果这个问题太初级了,那就抱歉了。我在《Programming Ruby》这本书里找不到答案(可能是没有仔细阅读)。无论如何,假设我有一个像下面这样的数组:

arr = [1,2,3,4,5]

…而且我想,比如将数组中的每个值乘以3,我已经想出了以下方法:

arr.each {|item| item *= 3}

......不会得到我想要的结果(我明白为什么,因为我没有修改数组本身)。

我不明白的是,如何在迭代器之后的代码块内修改原始数组。我相信这非常容易。

4个回答

153

使用map来从旧数组创建一个新数组:

arr2 = arr.map {|item| item * 3}

使用map!在原数组中进行修改:

arr.map! {|item| item * 3}

在线演示地址:ideone


2
如果你确实需要修改每个元素,使用 map 会更加优雅,我个人认为。 - fresskoma
2
如果你想修改数组本身,请使用map!。 - Yoann Le Touche

21

要直接修改数组,请使用arr.map!{|item| item*3}。要基于原始数组创建新数组(通常更好),请使用arr.map {|item| item*3}。实际上,在使用each之前,我总是要三思而后行,因为通常有一个高阶函数,比如mapselectinject可以完成我想做的事情。


如果您不想执行枚举操作怎么办?如果您只想执行类似于 arr.map!{ destructive_op} 的操作以永久更改 arr,该怎么办? - bright-star
1
@TrevorAlexander:我不确定你的意思。最好详细说明并提出一个真正的问题。 - Chuck
我需要考虑一下。除了非常狭窄的元素修改之外,对结构执行哪些破坏性操作是不可枚举的? - bright-star
@TrevorAlexander:我仍然很难理解。如果您无法查看结构的内容,则无法转换其内容。这听起来有点像您不想修改结构,而只是想分配一个变量 - 但我可能误解了。 - Chuck

5
arr.collect! {|item| item * 3}

0

其他人已经提到了,在这里使用array.map更加优雅的解决方案,但是你可以简单地在array.each的结尾加上一个"!",然后你仍然可以修改数组。在#map、#each、#collect等结尾添加"!"将修改现有的数组。


尝试过这个,但是在 each!each_with_index! 中都遇到了未定义的方法错误。 - Ryan Pierce Williams
这是错误的,因为Ruby中没有内置的方法像each!和each_with_index!。我建议你再检查一下你的答案,Andrew。这只适用于一些方法(map!,compact!,collect!,reject!等)。 - Sebastián Palma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接