views:

5143

answers:

4

Suppose I have the following object in javascript:

var object = {"key1":"value1","key2","value2","key3","value3"};

How do I find out how many tuples I have in the dictionary?

+3  A: 

You can iterate over the object to get the keys or values:

function numKeys(obj)
{
    var count = 0;
    for(var prop in obj)
    {
        count++;
    }
    return count;
}

It looks like a "spelling mistake" but just want to point out that your example is invalid syntax, should be

var object = {"key1":"value1","key2":"value2","key3":"value3"};

nexus
+10  A: 

There's no easy answer, because Object -- which every object in JS derives from -- includes many attributes automatically, and the exact set of attributes you get depends on the particular interpreter and what code has executed before yours. So, you somehow have to separate the ones you defined from those you got "for free".

Here's one way:

var foo = {"key1": "value1", "key2": "value2", "key3": "value3"};
Object.prototype.foobie = 'bletch'; // add property to foo that won't be counted

var count = 0;
for (var k in foo) {
    if (foo.hasOwnProperty(k)) {
       ++count;
    }
}
alert("Found " + count + " properties specific to foo");

EDIT: The second line shows how other code can add properties to all Object derivatives. If you remove the "hasOwnProperty()" check inside the loop, the property count will go up to at least 4. On a page with other JS besides this code, it could be higher than 4, if that other code also modifies the Object prototype.

Warren Young
You shouldn't use an empty object to access Object.prototype. Just use Object.prototype.hasOwnProperty.call(foo, k).
Eli Grey
why don't you just do foo.hasOwnProperty(k). Am I missing something? I mean even JavaScript type derives from Object.prototype, and it will have a hasOwnProperty() method.
bucabay
@Elijah: I don't see what's wrong with the way I did it, but yes, your way should work, too.
Warren Young
@bucabay: The purpose of the test is to find those properties of 'foo' that aren't present on every other Object derivative. It might be enlightening to remove the test, and see how high count goes. You'll find it to be in the dozens. Just for one, you'll find a reference to "hasOwnProperty()" in both 'foo' and 'empty', because "member functions" are properties of objects, too, not just data as in some other languages.
Warren Young
@WarrenYoung The statement empty.hasOwnProperty(k) will always be FALSE since empty objects have no immediate properties. foo.hasOwnProperty(k) will return only immediate properties, not inherited properties from Object.prototype.
bucabay
Try doing a test with: `Object.prototype.example = true;`
bucabay
I see the problem now. It's fixed, and I've added more to my answer to illustrate the point.
Warren Young
+1  A: 

This function makes use of Mozilla's __count__ property if it is available as it is faster than iterating over every property.

function countProperties(obj) {
  var count = "__count__",
  hasOwnProp = Object.prototype.hasOwnProperty;

  if (typeof obj[count] === "number" && !hasOwnProp.call(obj, count)) {
    return obj[count];
  }
  count = 0;
  for (var prop in obj) {
    if (hasOwnProp.call(obj, prop)) {
      count++;
    }
  }
  return count;
};

countProperties({
  "1": 2,
  "3": 4,
  "5": 6
}) === 3;
Eli Grey
Thanks for that!
kander