8

I am using javascript associative array like:

var testarray = [];
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';

I am also using jquery alongside. How can I check length of this associative array using jquery or any other method? Basically i want to check whether this array is empty or not.

Thank you.

Noelkd
  • 7,686
  • 2
  • 29
  • 43
Prashant
  • 81
  • 1
  • 1
  • 2
  • 1
    dupe; good answer @ http://stackoverflow.com/questions/5223/length-of-javascript-associative-array – Michael Paulukonis Mar 08 '10 at 15:06
  • 1
    JavaScript doesn't have "associative arrays", it has "arrays" and "objects". If you want to use named properties, use a plain object (`{}`) not an array. – Quentin Mar 08 '10 at 15:08
  • @David: Semantic point, but I'd say it the other way around: **All** JavaScript objects are associative arrays (not just the `Array` type, although of course it is as well). They have string keys that can be enumerated, entries that can be added and removed (`delete`) ad hoc, etc.. (Agreed that if you're not using numeric indexes, you don't want to use an `Array`.) – T.J. Crowder Mar 08 '10 at 15:35
  • 2
    Also, I'd like to point out that jquery is just a library - there is no need to worry about doing something 'using jquery' as you can just use plain old javascript, even if you're in the middle of a function callback that was triggered by some jquery invocations. Jquery is not a language - but it is very powerful. – belugabob Mar 08 '10 at 15:48
  • 1
    @belugabob: +1 and it doesn't get said enough, although it happens that in *this particular case*, jQuery helps (see CMS's answer). – T.J. Crowder Mar 08 '10 at 15:55

7 Answers7

21

You shouldn't use an array to store non-numeric indexes, you should use a simple object:

function getObjectLength (o) {
  var length = 0;

  for (var i in o) {
    if (Object.prototype.hasOwnProperty.call(o, i)){
      length++;
    }
  }
  return length;
}

Edit: Since you are using jQuery and you want to check if the object is "empty", the 1.4 version introduced the $.isEmptyObject

if ($.isEmptyObject(obj)) { 
  //...
}
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • ooh I like that you get "hasOwnProperty" from the Object prototype :-) – Pointy Mar 08 '10 at 15:09
  • You shouldn't use an array to store *only* non-numeric indexes (as I said in my answer), but I don't see any issue with *also* storing non-numeric information on arrays you're using for their "normal" purpose. – T.J. Crowder Mar 08 '10 at 15:10
  • Why not use the `hasOwnProperty` on `o` itself? To avoid it having possibly been replaced? – T.J. Crowder Mar 08 '10 at 15:13
  • @T.J. Crowder: Yes, safety first, otherwise `getObjectLength ({hasOwnProperty: 'foo'})` will make the function throw a `TypeError`... – Christian C. Salvadó Mar 08 '10 at 15:15
  • Thanks, I figured. I think I'd defer to the object author, though. If they have a good reason for overriding it, I should respect it (even if that means they blow things up for themselves). – T.J. Crowder Mar 08 '10 at 15:18
13

This gives you the length of your associative array:

Object.keys(testarray).length
Aditya
  • 4,453
  • 3
  • 28
  • 39
10

There's no direct "length" or "size" call, you have to test the keys available within the object.

Note that all JavaScript objects are associative arrays (maps), so your code would probably be better off using a generic object rather than an array:

var testarray = {}; // <= only change is here
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';

You can find out what the keys are in an object using for..in:

var name;
for (name in testarray) {
    // name will be 'one', then 'two', then 'three' (in no guaranteed order)
}

...with which you can build a function to test whether the object is empty.

function isEmpty(obj) {
    var name;
    for (name in obj) {
        return false;
    }
    return true;
}

As CMS flagged up in his answer, that will walk through all of the keys, including keys on the object's prototype. If you only want keys on the object and not its prototype, use the built-in hasOwnProperty function:

function isEmpty(obj) {
    var name;
    for (name in obj) {
        if (obj.hasOwnProperty(name)) {
            return false;
        }
    }
    return true;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 4
    And also don't forget about `hasOwnProperty()` to don't count properties from prototype. – MBO Mar 08 '10 at 15:10
  • 1
    probably should use the "hasOwnProperty" trick, something I wouldn't know about had I not become addicted to stackoverflow :-) – Pointy Mar 08 '10 at 15:10
2

I had this problem too, and I just realized the solution (and tested it in my browser):

//given: ass_arr, an associative array
//result: count now holds the "length" of ass_arr 
var count = 0;
$.each(ass_arr, function(key, val) { count+=1; } );
alert(count); //number of iterable attributes in ass_arr

Let me know if this works for you! I'm writing it right into my code like this:

var devices = STATUS.devices,
  num_devices = 0;
$.each(devices, function(id, device) { num_devices+=1; } );
//num_devices set to number of devices
Aaron
  • 2,049
  • 4
  • 28
  • 35
0

You don't really have an array there, so I'd avoid initializing it as such:

var testNotArray = { };
testNotArray['one'] = 'something';
// ...

Now this is inherently dangerous, but a first step might be:

function objectSize(o) {
  var c = 0;
  for (var k in o) 
    if (o.hasOwnProperty(k)) ++c;
  return c;
}

Again, there are a million weird ways that that approach could fail.

Andy E
  • 338,112
  • 86
  • 474
  • 445
Pointy
  • 405,095
  • 59
  • 585
  • 614
0

You could calculate the length like below:

var testarray = {}; // Use a generic object to store non-numeric indexes not an array
testarray['one'] = '1';
testarray['two'] = '2';
testarray['three'] = '3';
var count = 0
for each(key in testarray)
 count = count + 1
alert(count); // count contains the number of items in the array
ardsrk
  • 2,407
  • 2
  • 21
  • 33
0

You can loop through the properties to count them:

var cnt = 0;
for (i in testarray) cnt++;
alert(cnt);

Note that the for (... in ...) will also loop items added by a prototype, so you might want to count only the items added after that:

var cnt = 0;
for (i in testarray) if (testarray.hasOwnProperty(i)) cnt++;
alert(cnt);

If you just want to check if there are any properties, you can exit out of the loop after the first item:

var empty = true;
for (i in testarray) if (testarray.hasOwnProperty(i)) { empty = false; break; }
alert(empty);
Guffa
  • 687,336
  • 108
  • 737
  • 1,005