使用外部 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 #=&gt; [0.166..., 0.333..., 0.5]。相比之下,... ...a = [1,2,3]; a.map! |e| e.to_f/a.sum ; a #=&gt; [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 实例自身的主要内容,如果未能解决你的问题,请参考以下文章

带有实例或自定义回调函数的 PHP array_diff?

无法从创建它的方法外部访问 C-Array 元素

JS内置对象-String对象Date日期对象Array数组对象Math对象

高程三:Array

第五章自定义序列类

Array和String方法总结—实例