Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove elements of array in place returning the removed elements

Tags:

arrays

ruby

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}
like image 654
p1100i Avatar asked Oct 21 '25 16:10

p1100i


2 Answers

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.

like image 110
robinst Avatar answered Oct 23 '25 08:10

robinst


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

like image 30
krichard Avatar answered Oct 23 '25 07:10

krichard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!