Forum: Rails Spinoffs (closed, excessive spam) Problem inside #each

Posted by mocambo (Guest)
on 2008-06-23 05:14
(Received via mailing list)
I'm trying to remove all objects and object references from myArray.
But code below brakes before  last iteration - myArray contains still
one element.

myArray.each( function(content, index) {
    delete content; myArray.splice(index,1);
});

Is there any solution, how I can decrease this array inside #each ?
Posted by T.J. Crowder (Guest)
on 2008-06-23 09:40
(Received via mailing list)
Hi,

That's because you're modifying the array's contents within the
iterator, which is pretty much a no-no.  (You can modify the things
each array element points to, but changing the actual content of the
array is problematic.)  Just glancing at the #_each method in Array
(which is what #each calls) in prototype.js would reveal why:

    _each: function(iterator) {
        for (var i = 0, length = this.length; i < length; i++)
            iterator(this[i]);
    },

So #each probably isn't the best way to approach this.  Even if it
were, re-splicing the array every time is also going to be seriously
inefficient.

The good news is that all you need to do is set the array's length to
0.  You can do that directly, or call the tempting Prototype
Array#clear method:
http://www.prototypejs.org/api/array/clear

Setting the array's length automatically deletes any properties that
the new length would leave out; see the ECMA spec, Section 15.4:
http://www.ecma-international.org/publications/sta...

Hope this helps,
--
T.J. Crowder
tj / crowder software / com
Posted by mocambo (Guest)
on 2008-06-23 21:45
(Received via mailing list)
Thanks for your exhaustive explanation !

I've solved this issue following:

var _myArray = myArray.clone();

_myArray.each( function(content, index) {
    delete content; myArray.splice(index,1);

});

delete _myArray;
Posted by T.J. Crowder (Guest)
on 2008-06-23 23:03
(Received via mailing list)
> I've solved this issue following:

But....why?!  Just set the length to zero.  No need for all of the
cloning and splicing!
--
T.J. Crowder
tj / crowder software / com
Posted by Frederick Polgardy (Guest)
on 2008-06-23 23:22
(Received via mailing list)
You could always do it recursively. ;-)  If only JavaScript had tail
recursion!

function eraseArray(a) {
  delete a[0];
  if (a.length > 0)
    eraseArray(a.slice(1));
}

-Fred

On Mon, Jun 23, 2008 at 4:02 PM, T.J. Crowder <tj@crowdersoftware.com>
wrote:

>
> > I've solved this issue following:
>
> But....why?!  Just set the length to zero.  No need for all of the
> cloning and splicing!


--
Science answers questions; philosophy questions answers.
Posted by mocambo (Guest)
on 2008-06-24 01:00
(Received via mailing list)
Sorry for confusion !

My sample here was simplified. Actually I have much more logics inside
this #each. I'm using #splice method inside some conditional matches.

this.removeItems = function(item) {

    var _myArray = myArray.clone();

    _myArray.each( function(content, index) {
        ....
        if(content.regItem == item) { delete content;
myArray.splice(index,1); }
        ....
    });
}

If all .regItem's equal to item's, only then myArray should be empty.
Posted by kangax (Guest)
on 2008-06-24 03:32
(Received via mailing list)
There's a #reject for cases like this:

this.removeItems = function(item) {
  myArray = myArray.reject(function(_item, i) {
    return _item.regItem == item;
  })
}

- kangax
This topic is locked and can not be replied to.