Thanks for all the input -- I'm going with creating a new array for the
elements that need to be kept, now I know to never again delete from an
array while enumerating.  I use reject regularly, but that won't work in
this case.
James

On Thu, Oct 15, 2009 at 1:12 AM, Martin Emde <[email protected]> wrote:

>
> If you need to mutate the array, there's #reject!
>
> On Oct 15, 2009, at 0:23, Rob Kaufman <[email protected]> wrote:
>
> >
> > Martin mentions the reject method, which creates returns a new array,
> > it doesn't function on the existing array:
> >
> > a = [1,2,3,4,5]
> > => [1, 2, 3, 4, 5]
> > a.reject do |i| i == 5 end
> > => [1, 2, 3, 4]
> > a
> > => [1, 2, 3, 4, 5]
> >
> > However manipulating the value i during the iteration does not get
> > returned but it is what gets compared with.  For example
> >
> > a.reject do |i|
> >  i += 5
> >  puts i
> >  i == 6
> > end
> >> 6
> >> 7
> >> 8
> >> 9
> >> 10
> > => [2, 3, 4, 5]
> >
> > I have to agree with Pat that you usually don't want to modify the
> > array, but instead make a new one with the subset you care about.
> > reject or select are much better for that than each and delete or even
> > reverse_each and delete.  The cost of making the new Array is trivial
> > and actually much smaller than modifying the memory position of each
> > element several times as it collapses toward the front.  Having said
> > that if your manipulating the values AND trying to remove some on the
> > same pass your options are pretty limited.  At that point you can do
> > reverse_each or you can do inject.  Inject is the best in that
> > scenario:
> >
> > result = a.inject([]) do |new_array, i|
> >   i += 5
> >   if i == 6
> >     new_array # This is the value that becomes new_array on the next
> > pass
> >   else
> >    new_array << i
> >  end
> > end
> > => [7, 8, 9, 10]
> >
> > Best,
> > Rob
> >
> > On Wed, Oct 14, 2009 at 10:22, Pat Allan <[email protected]>
> > wrote:
> >>
> >> Modifying an array while enumerating over it - no matter what method
> >> you're using - is not a good idea.
> >>
> >> Also, if you just want to remove everything in an array:
> >>   array = ['a', 'b', 'c']
> >>   array.clear
> >>   array #=> []
> >>
> >> Cheers
> >>
> >> --
> >> Pat
> >>
> >> On 14/10/2009, at 6:48 PM, James Miller wrote:
> >>
> >>> Your explanation got me thinking that iterating in reverse might
> >>> work...it does!
> >>>
> >>> array = [ "a", "b", "c" ]
> >>> array.reverse_each do |item|
> >>>   array.delete(item)
> >>> end
> >>>
> >>> array => []
> >>>
> >>> Sweeeet....
> >>>
> >>> On Wed, Oct 14, 2009 at 9:40 AM, James Miller
> >>> <[email protected]> wrote:
> >>> Kerry - I ended up just creating a new array and adding elements to
> >>> it that I do want, which works fine.  Thanks for the explanation,
> >>> makes sense.
> >>>
> >>> David - Thanks for the explanation as well.  There's more code
> >>> involved in the actual implementation, where the array will
> >>> sometimes still contain items and sometimes be emptied in the
> >>> iteration.  My example was just to simplify and show the weirdness
> >>> when trying to empty the array via iteration rather than just
> >>> setting to [].
> >>>
> >>> Thanks,
> >>> James
> >>>
> >>>
> >>> On Wed, Oct 14, 2009 at 9:31 AM, Kerry Foley
> >>> <[email protected]> wrote:
> >>>
> >>> Hi James,
> >>> Strange right? Well, when you call delete within the loop it
> >>> confuses
> >>> each. The first time in you delete "a". The second time in you go to
> >>> the
> >>> 2nd element of the array, which is now "c" (not "b"). So you delete
> >>> "c"
> >>> and are left with array => ["b"].
> >>>
> >>> I assume you are are doing other things within the loop so one way
> >>> is to
> >>> save the items you want to delete into another array i.e.
> >>> to_be_deleted
> >>> and then do the deleting once you have exited the loop.
> >>>
> >>> Regards,
> >>> Kerry
> >>>
> >>> James Miller wrote:
> >>>> Hi Everyone,
> >>>>
> >>>> Wondering if someone could explain why this doesn't work as (I)
> >>>> expected...
> >>>>
> >>>> array = [ "a", "b", "c" ]
> >>>>
> >>>> array.each do |item|
> >>>>   array.delete(item)
> >>>> end
> >>>>
> >>>> array => [ "b" ]
> >>>>
> >>>> Why isn't the array empty ( array => [] )?  Is there a better
> >>> approach?
> >>>>
> >>>> Thanks,
> >>>> James
> >>>>
> >>>>
> >>>>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>
> >>
> >>
> >>>
> >>
> >
> >
> >
> > --
> > Rob Kaufman
> > http://notch8.com
> > gtalk/jabber/email: [email protected]
> > p: 858-412-7749
> > f: 866-477-1620
> >
> > >
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby
-~----------~----~----~----~------~----~------~--~---

Reply via email to