替换数组中的单个元素

25

我有一个唯一元素的数组。是否有一种方式可以在不使用索引值的情况下将其中某个值替换为另一个值?

示例:

array = [1,2,3,4]
if array.include? 4
#  "replace 4 with 'Z'"
end
array #=> [1,2,3,'Z']

hash = {"One" => [1,2,3,4]}
if hash["One"].include? 4
#  "replace 4 with 'Z'"
end
hash #=> {"One" => [1,2,3,'Z']}

你在这里寻找什么:array = [1,4,4]; if array.include? 4 # 将4替换为'Z' - Cary Swoveland
@CarySwoveland 是的,我只需要用我选择的另一个元素替换4(s)。[1,4,4] => [1,'Z','Z'] - Lasonic
我原以为只有第一个实例应该被替换,因为标题说“单个元素”。但事实并非如此。 - sawa
1
@sawa,我的所有数组都不会有重复元素,因此这并不重要。 - Lasonic
4个回答

39
p array.map { |x| x == 4 ? 'Z' : x }

# => [1, 2, 3, 'Z']

7
如果第一个元素等于4,为什么要遍历整个数组? - Cary Swoveland
7
你怎么知道数字“4”只在数组中出现了一次? - Matt Klein
从问题中:「我有一个具有唯一元素的数组」 - Stefan

20

你可以这样做:

array[array.index(4)] = "Z"
如果元素可能不在数组中,则
if i = array.index(4)
  array[i] = "Z"
end

1
他说他不想使用该项的索引值。 - Matheus Moreira
3
我同意你的意见,但我认为你的评论有点严厉。 - Mark Thomas
@MarkThomas 可能吧。但是我怀疑这篇帖子伴随着一个负评,让情况变得更糟。 - sawa
你不必怀疑。为什么你认为我的反对票可以证明你的反应是正确的?它只意味着我将来不会再费心解释了。 - Matheus Moreira

10

您可以使用Array#map

array = array.map do |e|
  if e == 4
    'Z'
  else
    e
  end
end

要原地编辑数组,而不是创建一个新数组,请使用Array#map!

如果你有多个想要替换的东西,可以使用哈希表将旧的映射到新的。

replacements = {
  4 => 'Z',
  5 => 'five',
}
array = array.map do |e|
  replacements.fetch(e, e)
end

这里使用了 Hash#fetch 的一个特性。如果没有找到键值,那么第二个参数会被用作默认值。


如果我的数组像更新中的哈希表一样呢? - Lasonic
2
@Lasonic 然后:hash['key'].map! do |e| ... end - Wayne Conrad

2

一个非常简单的解决方案,假设没有重复项并且顺序不重要:

hash = { 'One' => [1, 2, 3, 4] }

hash['One'].instance_eval { push 'Z' if delete 4 }

instance_eval 方法会在执行代码块期间将接收器(即数组[1,2,3,4])设置为self的值。


2
如果不是数组中的最后一个元素怎么办? - Lasonic
1
我不会那样做,但这很有趣。也许我们中间有一个流氓的踩负者。 - Cary Swoveland
如果顺序很重要,我认为Wayne的解决方案更好。它将替换4所有 出现,并保持它们的原始顺序,而无需使用任何索引。@Lasonic - Matheus Moreira
1
为了保证数组不重复,你可以使用 hash['One'].instance_eval { push('Z').uniq! if delete 4 }。 :) - Sony Santos
1
@BKSpurgeon,instance_eval 不会以任何方式修改接收器或其类。Array 类不会被修改。它所做的只是将 self 的值设置为接收器,并且此修改仅在传递给它的块中局部生效。 - Matheus Moreira
显示剩余3条评论

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