Array#delete_if! - a method to delete and return all array i


#1

Here’s a method to delete and return all items in an Array for which
the block evaluates to true:

class Array
def delete_if!
to_delete = []
to_keep = []
each do |item|
(yield item) ? to_delete << item : to_keep << item
end
replace(to_keep)
return to_delete
end
end

Demonstration:
irb(main):002:0> arr = (1…12).to_a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
irb(main):003:0> arr.delete_if! {|i| (i % 3) == 0}
[3, 6, 9, 12]
irb(main):004:0> arr
[1, 2, 4, 5, 7, 8, 10, 11]

Would people suggest better implementations? The obvious problem here
is that we’re duplicating arr (to_delete and to_keep contatin together
a cloned arr). I came up with an index based solution to avoid that,
but frankly it was quite ugly.


#2

On May 25, 2006, at 3:03 PM, Alder G. wrote:

Here’s a method to delete and return all items in an Array for which
the block evaluates to true:

[…]

Would people suggest better implementations? The obvious problem here
is that we’re duplicating arr (to_delete and to_keep contatin together
a cloned arr). I came up with an index based solution to avoid that,
but frankly it was quite ugly.

$ ri Array#reject!
---------------------------------------------------------- Array#reject!
array.reject! {|item| block } -> array or nil

  Equivalent to +Array#delete_if+, deleting elements from _self_ for
  which the block evaluates to true, but returns +nil+ if no changes
  were made. Also see +Enumerable#reject+.


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#3

On May 25, 2006, at 3:15 PM, Eric H. wrote:

together
a cloned arr). I came up with an index based solution to avoid that,
but frankly it was quite ugly.

$ ri Array#reject!

Oops, I meant:

$ ri partition
--------------------------------------------------- Enumerable#partition
enum.partition {| obj | block } => [ true_array, false_array ]

  Returns two arrays, the first containing the elements of _enum_

for
which the block evaluates to true, the second containing the rest.

     (1..6).partition {|i| (i&1).zero?}   #=> [[2, 4, 6], [1, 3, 5]]


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#4

Thanks. I didn’t know about #partition.

Still, if anyone can suggest an improved pure-ruby solution, I’d be
interested for educational reasons.

class Array
def delete_if!
to_delete = []
delete_if do |item|
to_delete << item if yield item
end
to_delete
end
end

irb(main):010:0> arr = [1,2,3,4,5,6]
=> [1, 2, 3, 4, 5, 6]
irb(main):011:0> arr.delete_if! {|x| x > 3}
=> [4, 5, 6]
irb(main):012:0> arr
=> [1, 2, 3]


#5

On 5/26/06, Eric H. removed_email_address@domain.invalid wrote:

On May 25, 2006, at 3:15 PM, Eric H. wrote:

$ ri partition


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Thanks. I didn’t know about #partition.

Still, if anyone can suggest an improved pure-ruby solution, I’d be
interested for educational reasons.


#6

On 5/26/06, Daniel S. removed_email_address@domain.invalid wrote:

  to_delete << item if yield item

=> [1, 2, 3]

Yup, good one. Thanks.