Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do `Hash#reject!` and `Hash#reject` differ from `Hash#delete_if`?

Tags:

ruby

How do reject! and reject differ from delete_if for a Hash in Ruby? Can anyone explain the differences between them with simple code snippets?

like image 886
Arup Rakshit Avatar asked Dec 04 '22 00:12

Arup Rakshit


2 Answers

Since the other answers are referring to Array#delete_if and not Hash#delete_if, which seems to be what you are asking, I thought I should clarify.

As others have pointed out, reject and reject! differ in that reject! version modifies the hash in-place, while reject creates a new hash. Meanwhile delete_if is almost the same as reject!.

In fact, for an Array, reject! and delete_if are exactly the same.

However, for a Hash, they are slightly different. reject! returns nil if no changes were made, or the hash if changes were made. delete_if always returns the hash.

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

So if you wanted to check whether changes were made to the hash after deleting the elements, you could use reject! and check the return value.

like image 196
Andrew Haines Avatar answered Mar 07 '23 07:03

Andrew Haines


If you read the docs it tells you that reject! is "Equivalent to Array#delete_if"

reject and reject! differ in that the bang (reject!) causes the changes to happen directly on the array you're working with, whereas reject will leave the array you're working with untouched, but will return a new array.

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"]
like image 36
99miles Avatar answered Mar 07 '23 06:03

99miles