Array#delete_if! - a method to delete and return all array items for which the block evaluates to true

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.

···

--
-Alder

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

···

On May 25, 2006, at 3:03 PM, Alder Green wrote:
------------------------------------------------------------------------
      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 Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Oops, I meant:

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

···

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

On May 25, 2006, at 3:03 PM, Alder Green 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!

------------------------------------------------------------------------
      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 Hodel - drbrain@segment7.net - 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.

···

On 5/26/06, Eric Hodel <drbrain@segment7.net> wrote:

On May 25, 2006, at 3:15 PM, Eric Hodel wrote:
...
$ ri partition

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

--
-Alder

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]

Yup, good one. Thanks.

···

On 5/26/06, Daniel Sheppard <daniels@pronto.com.au> wrote:

> 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]

--
-Alder