【问题标题】:What is destructive?什么是破坏性的?
【发布时间】:2023-08-22 07:09:02
【问题描述】:

我知道 Ruby 有很多方法,尤其是在数组或类似数组的对象上,例如 sortflatten。但是,这些方法也有一个孪生方法(带有感叹号的那个),例如 sort!flatten!

现在我的问题是:

  • flattenflatten!(破坏性展平)有什么区别?
  • 一个更普遍的问题,为什么它被称为破坏性的?

【问题讨论】:

  • 您是否阅读过flattenflatten! 的文档?通过阅读说明和示例很容易分辨。

标签: ruby arrays flatten


【解决方案1】:

区别只是flatten 返回数组的副本(一个被展平的新数组),而flatten! 则“就地”或“破坏性地”进行修改。破坏性一词意味着它修改了原始数组。当您知道想要最终结果是什么并且不介意原始结构是否发生变化时,这很有用。

正如@padde 指出的那样,由于结构可能很大并且复制成本很高,因此执行破坏性操作也会消耗更少的内存。

但是,如果您想保留原始结构,最好使用该方法并制作副本。

这是一个使用sortsort! 的示例。

a = [9, 1, 6, 5, 3]
b = a.sort
c = [7, 6, 3]
c.sort!

内容:

a = [9, 1, 6, 5, 3]
b = [1, 3, 5, 6, 9]
c = [3, 6, 7]

【讨论】:

  • 附带说明:有时变异器比它们的无手镯等价物快得多。根据底层算法和数据量,可以节省大量复制。
【解决方案2】:

Array#flatten:- 返回一个新数组,它是自我的一维展平(递归)。

Array#flatten!:- 将自身展平。

a = [1,2,[3,4]]
p a.object_id #=> 74502050
p a.flatten.object_id #=> 74501960
p a.flatten!.object_id #=> 74502050

flatten 创建一个新的数组对象,因为a.flatten.object_id 显示的值与a.object_id 不同。

flatten! 修改a 引用的对象,a.flatten!.object_id 显示为74502050

【讨论】: