“Hash#reject!”和“Hash#reject”与“Hash#delete_if”有何不同?

时间:2013-01-13 20:02:15

标签: ruby

对于reject!rejectdelete_ifHash的区别如何?任何人都可以用简单的代码片段解释它们之间的差异吗?

3 个答案:

答案 0 :(得分:12)

由于其他答案指的是Array#delete_if而不是Hash#delete_if,这似乎就是您的要求,我认为我应该澄清。

正如其他人所指出的那样,rejectreject!的不同之处在于reject!版本就地修改了哈希,而reject创建了一个新哈希。同时delete_if 几乎reject!相同。

事实上,对于Arrayreject!delete_if 完全相同

然而,对于Hash,它们略有不同。如果未进行任何更改,则reject!会返回nil,如果进行了更改,则会返回哈希值。 delete_if始终返回哈希值。

hash = {a: 1, b: 2, c: 3}

return_value = hash.delete_if {|k, v| v > 100}
# hash is unchanged, return_value is {a: 1, b: 2, c: 3}

return_value = hash.reject! {|k, v| v > 100}
# hash is unchanged, return_value is nil

因此,如果要在删除元素后检查是否对哈希进行了更改,可以使用reject!并检查返回值。

答案 1 :(得分:2)

我想你可以从文档中读到这个:

http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-reject-21

  

等效于Array#delete_if,从块中计算为true的self中删除元素,但如果没有进行任何更改则返回nil。每次调用块时都会立即更改数组,而不是在迭代结束后更改。另请参见Enumerable#reject和Array#delete_if。   如果没有给出块,则返回枚举器。

http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-reject

  

返回一个新数组,其中包含块不为true的self项。另请参见Array#delete_if   如果没有给出块,则返回枚举器。

答案 2 :(得分:2)

如果您阅读文档,它会告诉您拒绝!是“等同于数组#delete_if”

拒绝并拒绝!不同之处在于,爆炸(拒绝!)导致更改直接发生在您正在使用的阵列上,而拒绝将使您正在使用的阵列保持不变,但会返回一个新阵列。

a = [ "a", "b", "c" ]
b = a.reject {|x| x >= "b" }   #=> a is untouched, but b is ["a"]
a.reject! {|x| x >= "b" }   #=> a is now modified and is ["a"]