views:

19421

answers:

6

If I have a javascript associative array say:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;

Is there a built in or accepted best practice way to get the length of this array?

EDIT: JavaScript does not have associative arrays -- it only has objects.

+1  A: 

It's not really an associative array (edit: IMHO, docs apparently say otherwise). You're basically doing this

myArray.firstname = "Gareth";

So I don't think you can get the length. You might try using something like Prototype's hash.

palmsey
A: 

I'm not a javascript expert but it looks like you would have to loop through the elements and count them since Object doesn't have a length method:

var element_count = 0;
for (e in myArray) { element_count++; }

@palmsey: In fairness to the OP, the javascript docs actually explicitly refer to using variables of type Object in this manner as "associative arrays".

jj33
+7  A: 

Specify a prototype size() function for Object:

Object.prototype.size = function () {
var len = this.length ? --this.length : -1;
for (var k in this)
len++;
return len;
}

Then create the object:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;

Then you can do things like:

alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
superjoe30
I like your approach better than @James, his looks like Python.
Fabiano PS
+1  A: 

@jj33: You might want to test if the property is not on the prototype chain...

var element_count = 0;
for(var e in myArray)
if(myArray.hasOwnProperty(e))
element_count++;
doekman
A: 

@palmsey: In fairness to the OP, the javascript docs actually explicitly refer to using variables of type Object in this manner as "associative arrays".

And in fairness to @palmsey he was quite correct, they aren't associative arrays, they're definitely objects :) - doing the job of an associative array. But as regards the wider point you definitely seem to have the right of it according to this rather fine article I found:

JavaScript “Associative Arrays” Considered Harmful

But according to all this, isn't the accepted answer itself bad practice?

Specify a prototype size() function for Object

If anything else has been added to Object .prototype, then the suggested code will fail:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

I don't think that answer should be the accepted one as it can't be trusted to work if you have any other code running in the same execution context. To do it in a robust fashion surely you would need to define the size method within myArray and check for the type of the members as you iterate through them.

Flubba
+45  A: 

The most robust answer (i.e. that captures the intent of what you're trying to do while causing the fewest bugs) would be:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

There's a sort of convention in JavaScript that you don't add things to Object.prototype, because it can break enumerations in various libraries. Adding methods to Object is usually safe, though.

awesome concept!
gmiernicki