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