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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B780ee0ee1480454a85df58536702f63?d=identicon&s=25 Alder Green (Guest)
on 2006-05-26 00:05
(Received via mailing list)
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.
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-26 00:17
(Received via mailing list)
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!
---------------------------------------------------------- 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 Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-26 00:21
(Received via mailing list)
On May 25, 2006, at 3:15 PM, Eric Hodel 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 Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
B780ee0ee1480454a85df58536702f63?d=identicon&s=25 Alder Green (Guest)
on 2006-05-26 01:32
(Received via mailing list)
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

Thanks. I didn't know about #partition.

Still, if anyone can suggest an improved pure-ruby solution, I'd be
interested for educational reasons.
1c1e3bdfe006a22214102fcd6434a012?d=identicon&s=25 Daniel Sheppard (Guest)
on 2006-05-26 01:53
(Received via mailing list)
> 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]
B780ee0ee1480454a85df58536702f63?d=identicon&s=25 Alder Green (Guest)
on 2006-05-26 02:05
(Received via mailing list)
On 5/26/06, Daniel Sheppard <daniels@pronto.com.au> wrote:
>       to_delete << item if yield item
> => [1, 2, 3]
>

Yup, good one. Thanks.
This topic is locked and can not be replied to.