RogerWilgo
RogerWilgo

Reputation: 77

How can I have the real count of an array?

I tried this way, but it returns me the wrong count:

myArr = [];
myArr[666] = 'hello there';
console.log(myArr.length); // returns me 667

It should be 1. How can I have the good count in the fastest way?

Upvotes: 6

Views: 384

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1074038

It should be 1.

No, it should be 667, because that's how length is defined for standard arrays in JavaScript, which aren't really arrays at all. Arrays in JavaScript are inherently sparse, meaning they can have holes in them (indexes where no value of any kind is stored).

How can I have the good count in the fastest way?

The only way is by looping. For instance:

var count = 0;
myArr.forEach(function() {
    ++count;
});
console.log(count);

...or via reduce as in maček's answer. forEach, reduce, and other such only visit entries that actually exist, so they skip the holes in sparse arrays.


I should mention that since IE8 still (sigh) has a fair bit of market share, you need to shim forEach and reduce and such on it if you want to use them. (Which is easy.)

To do this without any shimming, and only count actual index properties (not other kinds of properties), then loosely:

var count = 0, name;
for (name in myArr) {
    if (myArr.hasOwnProperty(name) && /^[0-9]+$/.test(name)) {
        ++count;
    }
}

That uses a slightly loose definition of what an index property name is; if you want a robust one, see the "Use for-in correctly" part of this answer.

Upvotes: 17

John Bupit
John Bupit

Reputation: 10618

You can use Object.keys().

Object.keys(myArr).length;

From the documentation:

Object.keys returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.

This function is compatible with IE9+. The documentation also contains a funtion that can be added for compatibility in all browsers:

if (!Object.keys) Object.keys = function(o) {
  if (o !== Object(o))
    throw new TypeError('Object.keys called on a non-object');
  var k=[],p;
  for (p in o) if (Object.prototype.hasOwnProperty.call(o,p)) k.push(p);
  return k;
}

Upvotes: 4

maček
maček

Reputation: 77778

You can count the number of non-undefined properties using a reduce

var length = myArr.reduce(function(len) { return len+1; }, 0);
console.log(length); // 1

Upvotes: 8

Tripp Kinetics
Tripp Kinetics

Reputation: 5439

Because arrays are indexed by 0. [0...666] is 667 items. If you actually want a count of how many items you have, an array might not be the best solution.

Upvotes: 5

Related Questions