views:

10515

answers:

5

What's the fastest way to count the number of keys/properties of an object? It it possible to do this without iterating over the object? i.e. without doing

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

Firefox provides a magic __count__ property, but this isn't available in other implementations.

+4  A: 

I don't think this is possible (at least not without using some internals). And I don't think you would gain much by optimizing this.

amix
+7  A: 

Are you actually running into a performance problem? If so, I would suggest wrapping the calls that add/remove properties to/from the object with a function that also increments/decrements an appropriately named (size?) property, so you only need to calculate the initial number of properties once and move on from there. If there isn't an actual performance problem, don't bother. Just wrap that bit of code in a function getNumberOfProperties(object) and be done with it.

Confusion
+7  A: 

I'm not aware of any way to do this, however to keep the iterations to a minimum, you could try checking for the existance of __count__ and if it doesn't exist (ie not Firefox) then you could iterate over the object and define it for later use eg:

if (myobj.__count__ === undefined) {
  myobj.__count__ = ...
}

This way any browser supporting __count__ would use that, and iterations would only be carried out for those which don't. If the count changes and you can't do this, you could always make it a function:

if (myobj.__count__ === undefined) {
  myobj.__count__ = function() { return ... }
  myobj.__count__.toString = function() { return this(); }
}

This way anytime you reference myobj.__count__ the function will fire and recalculate.

Luke Bennett
Note that `Object.prototype.__count__` is being removed in Gecko 1.9.3:http://whereswalden.com/2010/04/06/more-changes-coming-to-spidermonkey-the-magical-__count__-property-of-objects-is-being-removed/
dshaw
+7  A: 

I just stumbled on this question. It's quite old, but since there's no accepted answer try this:

keys(myObj).length

I'm not sure how efficient this is, but it requires the least amount of code :)

Rhinosaurus
I don't think that's supported by ie, however, if I type keys into the safari web console I get: function (o) { var a = []; for (k in o) a.push(k); return a; }I would say thats slower than just doing the count. Plus, it doesn't take into account the hasOwnProperty.
Russell Leggett
The length property isn't supported in objects in Firefox; only arrays.
scotts
@scotts - I'd expect `keys()` to return an array... but I'm not super-well-versed in Javascript's intricacies.
Matchu
Er, I think `keys` is a utility function in the console. That's why you can see its definition. It won't work in JavaScript code on the page.
Sidnicious
Note that Object.keys is supported by Firefox 4, Chrome 6, Safari 5, IE 9 and above: var o = {"foo": 1, "bar": 2}; alert(Object.keys(o));
Sam Dutton
+1  A: 

In jQuery, you could do this:

alert($.param({'a':33,'b':44}).split('&').length);

think of "{}", you should use:

alert($.param(obj).split('=').length);

for diyism

diyism
jQuery seems like overkill.
Matchu