为什么delete会返回已删除的元素而不是新数组?

时间:2014-11-02 01:10:21

标签: ruby

在ruby中,Array#delete(obj)将从数组中搜索并删除指定的对象。但是,我可能会在这里遗漏一些东西,但我发现返回值--- obj本身 - 很奇怪,甚至有点无用。

我的拙见是,与sort/sort!map/map!等方法一致,应该有两种方法,例如delete/delete!,其中

ary.delete(obj) -> new array, with obj removed
ary.delete!(obj) -> ary (after removing obj from ary)

由于多种原因,首先是当前的delete是非纯的,它应该像Array中的许多其他方法一样警告程序员(事实上整个delete_???家庭有这个问题,它们是非常危险的方法!),其次是返回obj比返回新数组的链式要小得多,例如,如果delete就像上面描述的那样,然后我可以在一个语句中执行多个删除操作,或者删除后我可以执行其他操作:

ary = [1,2,2,2,3,3,3,4]
ary.delete(2).delete(3)      #=> [1,4], equivalent to "ary - [2,3]"
ary.delete(2).map{|x|x**2"}  #=> [1,9,9,9,16]

优雅且易于阅读。

所以我想我的问题是:这是出于某种原因的故意设计,还是仅仅是语言的遗产?

2 个答案:

答案 0 :(得分:4)

如果您已经知道delete总是危险的,则无需添加爆炸!以进一步注意它是危险的。这就是为什么它没有它。像map这样的其他方法可能有危险,也可能没有危险;这就是为什么他们有没有爆炸的版本。

至于为什么它返回提取的元素,它提供了对信息的访问,如果它不是那样设计的,那么这些信息很难引用。修改后的原始数组可以通过访问接收器轻松引用,但提取的元素不易访问。

也许,您可能会将此与添加元素的方法进行比较,例如pushunshift。这些方法添加元素而不管接收器数组具有哪些元素,因此返回添加的元素将始终与传递的参数相同,并且您知道它,因此返回添加的元素没有帮助。因此,返回修改后的数组,这更有帮助。对于delete,是否提取元素取决于接收器数组是否具有它,并且您不知道它,因此将它作为返回值是有用的。

答案 1 :(得分:0)

对于那些可能会问同一个问题的人,我想我现在对它的了解更多,所以我不妨分享一下这个问题的方法。

所以简短的回答是,ruby不是最初为函数式编程设计的语言,也不是将方法的纯度放在首位。

另一方面,对于我在问题中描述的特定应用,我们确实有其他选择。在大多数情况下,-方法可以用作delete的纯替代方法,例如,我的问题中的代码可以像这样实现:

ary = [1,2,2,2,3,3,3,4]
ary.-([2]).-([3])         #=> [1,4], or simply ary.-([2,3])
ary.-([2]).map{|x|x**2"}  #=> [1,9,9,9,16]

您可以愉快地从-的纯度中获得所有好处。对于delete_if,我猜在大多数情况下select(返回值被否定)可能是一个不那么伟大的纯粹候选人。

至于为什么delete家庭的设计是这样的,我认为这在观点上更具差异性。对于通常需要的非纯粹程序而言,它们应该是更多的缩写,而不是与功能性selectmap等并列。