使用外部 Array 方法修改 Array 实例自身
Posted
技术标签:
【中文标题】使用外部 Array 方法修改 Array 实例自身【英文标题】:Modifying Array instances self with external Array method 【发布时间】:2022-01-05 19:56:59 【问题描述】:在练习 ruby 时,我写了一个这样的类:
class Array
def my_each
c = 0
until c == size
yield self[c]
c += 1
end
end
def my_map
c = 0
acc = []
my_each |e| acc << yield(e)
acc
end
end
def plus_two(a)
a += 2
end
nums = [1, 2, 3, 4, 5]
nums.my_map |e| plus_two(e)
p nums
效果很好,符合预期。但是,我想实现修改实例的Array#my_map!
,但我不知道如何以这种方式修改现有数组。
据我所知(我是一名有 Java 经验的初学者 Ruby 开发人员)我们可以通过 @
访问实例变量,但在这种情况下,我想不出最佳实践。解决这种情况的体面方法是什么?
谢谢。
【问题讨论】:
如果你增加c
,你可以使用self[c] = new_value
来设置索引c
的值
c
是迭代器索引。我们正在迭代 self 实例以一个一个地产生对象。
是的,您可以将来自yield
的结果通过self[c] = …
存储回数组。
好主意!谢谢。
【参考方案1】:
我添加了一个Array#my_map!
方法,如下所示:
def my_map!
self.replace(my_map |e| yield(e))
end
所以我们需要用我们的新临时实例替换实例(self)。效果很好。
【讨论】:
my_map
未定义。我猜你的意思是class Array; def my_map!; self.replace(map |e| yield(e)); end; end
,在这种情况下self.
是多余的,但没有害处。也就是说,操作行可以写成replace(map |e| yield(e))
。但是,这并不总是产生与Array#map!
相同的结果。假设a = [1,2,3]
。然后a.my_map! |e| e.to_f/a.sum ; a #=> [0.166..., 0.333..., 0.5]
。相比之下,...
...a = [1,2,3]; a.map! |e| e.to_f/a.sum ; a #=> [0.166..., 0.387..., 0.844...]
。如您所见,map!
与 my_map!
不同的是,a
的元素一个接一个地改变,这会影响a.sum
。您需要采纳@Stefan 的建议。
bang 方法接管非 banged 的优点是它们节省了复制所需的执行时间。因此,replace
方法是反作用的。更好的复制是self[c]=...
解决方案,让非爆炸版本只调用dup
,然后是爆炸版本。
@CarySwoveland my_map 在我提到的类中定义。但是,您的回答完全消除了我的困惑:)。谢谢!
@bertramscharpf 我已经修改了你所说的方法。谢谢你的帮助。以上是关于使用外部 Array 方法修改 Array 实例自身的主要内容,如果未能解决你的问题,请参考以下文章