2014-11-02 57 views
2

在ruby中,Array#delete(obj)将搜索并从数组中移除指定的对象。然而,可能是我在这里错过了一些东西,但我发现返回值--- obj本身---很奇怪,甚至有点无用。为什么delete会返回删除的元素而不是新的数组?

我个人认为,与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] 

这是优雅和易于阅读。

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

+0

相关:http://stackoverflow.com/a/26533811/1301972 – 2014-11-02 01:58:03

+0

[Array#delelte_if](http://www.ruby-doc.org/core-2.1.1/Array.html#methodi-i -delete_if)可以做你想做的事:'a = [1,2,3]; a.delete_if {| e | e == 2} => [1,3]; a => [1,3]'或'[1,2,3] .delete_if {| e | e == 2} .map {| e | e ** 2} => [1,9]'。另一方面,'如果arr.delete(3)...'通常非常方便,并且比'sz = arr.size更好;如果sz-arr.delete.size> 0 ...'(即,如果delete返回结果数组)。我不认为你可以评估一个方法的规格与其他方法的独立性。 Ruby语言僧侣非常敏锐,通常他们的工作有很好的理由。 – 2014-11-02 03:35:02

回答

4

如果你已经知道delete总是危险的,没有必要添加砰!进一步注意到它是危险的。这就是为什么它没有它。其他方法如map可能会也可能不会危险;这就是为什么他们有和没有爆炸的版本。至于为什么它返回提取的元素,它提供了访问信息,如果它不是这样设计的,那么这些信息是很麻烦的。修改后的原始数组很容易通过访问接收器来引用,但提取的元素不容易访问。也许,您可能会将其与添加元素的方法(如pushunshift)进行比较。这些方法添加了元素,而不管接收者数组具有哪些元素,因此返回添加的元素将始终与传递的参数相同,并且您知道它,因此返回添加的元素没有帮助。因此,返回修改的数组,这更有帮助。对于delete,元素是否被提取取决于接收者数组是否拥有它,并且您不知道,因此将其作为返回值很有用。

+1

谢谢。你的回答很有帮助。 :) – trVoldemort 2014-11-02 03:10:29

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

相关问题