4

I have an array arr. I want to destructively remove elements from arr based on a condition, returning the removed elements.

arr = [1,2,3] arr.some_method{|a| a > 1} #=> [2, 3] arr #=> [1] 

My first try was reject!:

arr = [1,2,3] arr.reject!{|a| a > 1} 

but the returning blocks and arr's value are both [1].

I could write a custom function, but I think there is an explicit method for this. What would that be?

Update after the question was answered:

partition method turns out to be useful for implementing this behavior for hash as well. How can I remove elements of a hash, returning the removed elements and the modified hash?

hash = {:x => 1, :y => 2, :z => 3} comp_hash, hash = hash.partition{|k,v| v > 1}.map{|a| Hash[a]} comp_hash #=> {:y=>2, :z=>3} hash #=> {:x=>1} 
0

3 Answers 3

5

I'd use partition here. It doesn't modify self inplace, but returns two new arrays. By assigning the second array to arr again, it gets the results you want:

comp_arr, arr = arr.partition { |a| a > 1 } 

See the documentation of partition.

Sign up to request clarification or add additional context in comments.

Comments

1

All methods with a trailing bang ! modify the receiver and it seems to be a convention that these methods return the resulting object because the non-bang do so.
What you can to do though is something like this:

b = (arr.dup - arr.reject!{|a| a>1 }) b # => [2,3] arr #=> [1] 

Here is a link to a ruby styleguide which has a section on nameing - although its rather short

Comments

0

To remove (in place) elements of array returning the removed elements one could use delete method, as per Array class documentation:

a = [ "a", "b", "b", "b", "c" ] a.delete("b") #=> "b" a #=> ["a", "c"] a.delete("z") #=> nil a.delete("z") { "not found" } #=> "not found" 

It accepts block so custom behavior could be added, as needed

1 Comment

delete doesn't allow specify a condition (a > 1) and – as shown in your example – it also only returns the last deleted item, even if multiple items have been removed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.