0

JavaScript has some funny quirks here and there. Consider this quirk, ripped from this awesome post (thanks to M. Staveley for sharing this):

var colours = ['red', 'green', 'blue']
// is red really in the array?
console.log(colours.indexOf('red') > -1);  // outputs true. 
// remove red, it's going out of fashion!
delete colours[colours.indexOf('red')];
console.log(colours.indexOf('red') > -1);  // outputs false
console.log(colours.length) // length is still three, remember it's javascript!

Last line is what bugs me. This quirk has the best of my curiosity, what's an elegant way to get access of real count of colours?

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
Stephane Gosselin
  • 9,030
  • 5
  • 42
  • 65

5 Answers5

2

Don't use delete

You should use one of the native array functions, like splice or shift

colours.shift();
console.log(colours.length);

or

colours.splice(colours.indexOf('red'), 1);
console.log(colours.length);
ericb
  • 3,400
  • 1
  • 21
  • 21
2

That's a misuse of Javascript arrays really, so while there is a workaround (use for...in and count the number of properties whose names are numbers) you would certainly not call it elegant (see it in action).

Don't use delete and don't manually assign indexes to elements (var colors = []; colors[1000] = 'red';); it's not how arrays are meant to be used.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

delete will only delete the element's reference. It won't update the array's logic, and there's no elegant way to get the real count of variables in such a broken array (see Jon's suggestion). So use shift, pop, splice or var newarray = oldarray.slice.

See also:

Community
  • 1
  • 1
Zeta
  • 103,620
  • 13
  • 194
  • 236
1

delete just sets the value to undefined, it doesn't remove it from the array.

delete colours[colours.indexOf('red')];

Your array now looks like this:

[undefined, 'green', 'blue']

As, you can see, the length is still 3. To remove a value from an array, you can use splice.

colours.splice(colours.indexOf('red'), 1);
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
1

using delete to remove items in an array but leaves "holes" in the array. it deletes the value but not it's "space", making the array still have the same length.

to remove a value as well as the space in that array, use splice

array.splice(colours.indexOf('red'),1); //remove 1 item starting from index
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • Do you know where this is defined in the spec? Looking at the [section on `delete`](http://es5.github.com/#x8.12.7), I can't find anything about the behaviour as applied to an array. – James Allardice Apr 18 '12 at 22:25
  • @JamesAllardice a [similar answer](http://stackoverflow.com/a/500617/575527) also mentions this. delete makes the item `undefined`. since is still a value, it retains the space, it does not change the array length. try it out. – Joseph Apr 18 '12 at 22:30
  • I know that this is what happens, but I am asking why does it happen? Is this behaviour defined in the spec? That answer just demonstrates the same behaviour as yours. – James Allardice Apr 18 '12 at 22:31
  • @JamesAllardice i don't really read specs. I just know that it's the way to to it though. – Joseph Apr 18 '12 at 22:38
  • 2
    Fair enough. I know it is the way to do it, and I have never used `delete` with an array, but now the question has been asked I just like to find out exactly what's going on under the hood. – James Allardice Apr 18 '12 at 22:40