Feature #21791
openImplement Set#compact/Set#compact!, these should return Set instead of Array
Description
I recently had to remove a nil value from a Set, and ended up with an Array:
irb(main):001> Set[1, 2, nil, 3].compact
=> [1, 2, 3]
irb(main):002> Set[1, 2, nil, 3].compact.class
=> Array
Since there is no dedicated Set#compact, this is done via Enumerable#compact and this results in an Array. To preserve the Set, the following works:
set - [nil] # compact
set.delete_if(&:nil?) # compact!
set.compact.to_set # compact, but slow
Both are rather ugly.
This patch implements Set#compact and Set#compact! in a way that preserves the class.
There are probably more methods that could have their own implementation, for example Set#select/Set#reject now returns arrays too (but Set#select! and Set#reject! work as expected.
Pull request: https://github.com/ruby/ruby/pull/15614
Updated by herwin (Herwin W) 4 days ago
I wrote the rubyspecs for this change as well, they now check for version 4.0, but since we're very late into the 4.0 release cycle, it might be better to bump this to 4.1.
Updated by byroot (Jean Boussier) 3 days ago
Since Set#delete is O(1) performance and return self, why not just:
>> Set[1, 2, nil, 3].delete(nil)
=> Set[1, 2, 3]