If you take an array and do the following:
arr = [];
arr[100] = 1;
The length will be 101, which makes sense due to 0-99 being set as undefined
Now if we sort that array: arr.sort() it will look like this: [1, undefined x100] since keys are not preserved. However, the length is still 101, since the undefined have all been moved to the end, instead of removed.
Is this behavior intentional and if so: is there a built-in function that removes undefined and recalculates and why is it intentional?
I am not asking how to write my own function to recalculate length. A sorted array’s length can easily be forced with for (x = 0; arr[x] != undefined; x++);arr.length = x;
The array has only one member at 100, it is like:
No, it doesn’t. It has one member at 0 and a length of 100. There aren’t 100 members with a value of ‘undefined’.
If you wish to reduce the array to only the defined members, there is no built–in function to do that (i.e. essentially to set the length to the highest index that has a value).
You can only do that by iterating over the array, e.g. by reducing the length from the right until an existing property is reached:
Note that for the above to work properly, the array must be sorted. Also, it modifies the array passed in.
Here’s a way to extend Array.prototype with a compress method so an array exists of only the defined members and the length is reset appropriately:
Note that it will not remove members whose value is undefined, only those that don’t exists at all. So:
Edit
As pointed out by zzzzBov, this can also be done using
filter:which will replace
xwith a new array of only the defined members regardless of their value. It will be non-sparse (or contiguous) and have an appropriate length, e.g.Note that this method will only update the array referenced by x, it will not update any other reference to the same array, e.g.
this may be useful behaviour if there is a requirement to keep the original array. In contrast, the
compressmethod modifies the original array:I have no idea if there is an intention to add such a method to
Array.prototypein future versions of ECMAScript or what it might be called, so a different name might be advisable, sayxcompressor similar, to avoid unintended conflict with future versions and to make it obvious that it’s a native method, not built–in.I’m also a bit stumped for a suitable name, since packed and compressed already have defined meanings that are different to non–contiguous, but that seems unwieldy so it’s compress for now.