94

I have an object something like:

Object {0=Object, 1=Object, 2=Object} // Output from console.log(obj.Data);

But there is no way that I can count the number of objects in object, then finally get the attribute value from the sub objects.

I have tried

console.log(obj.Data[0].length); // It does not work

console.log(obj.Data.length); // It does not work

This is a bit tricky for me. Hope you guys can help.

Bryan Learn
  • 1,333
  • 2
  • 14
  • 13
  • 1
    could you please post complete object? – Zain Shaikh Jun 07 '13 at 05:36
  • 1
    Why are you using an object this way? There's a lot of things to consider to your question - you need to understand what properties are, which ones are enumerable, how prototypes can add to the mess here, and so on. Why not just use an array? – Sacho Jun 07 '13 at 05:39
  • Even though this q is marked a duplicate, the accepted answer here works easier for me that the solutions given in the first asked question. – Anshu Prateek Feb 18 '16 at 09:53

3 Answers3

129

The easiest way to do this, with excellent performance and compatibility with both old and new browsers, is to include either Lo-Dash or Underscore in your page.

Then you can use either _.size(object) or _.keys(object).length

For your obj.Data, you could test this with:

console.log( _.size(obj.Data) );

or:

console.log( _.keys(obj.Data).length );

Lo-Dash and Underscore are both excellent libraries; you would find either one very useful in your code. (They are rather similar to each other; Lo-Dash is a newer version with some advantanges.)

Alternatively, you could include this function in your code, which simply loops through the object's properties and counts them:

function ObjectLength( object ) {
    var length = 0;
    for( var key in object ) {
        if( object.hasOwnProperty(key) ) {
            ++length;
        }
    }
    return length;
};

You can test this with:

console.log( ObjectLength(obj.Data) );

That code is not as fast as it could be in modern browsers, though. For a version that's much faster in modern browsers and still works in old ones, you can use:

function ObjectLength_Modern( object ) {
    return Object.keys(object).length;
}

function ObjectLength_Legacy( object ) {
    var length = 0;
    for( var key in object ) {
        if( object.hasOwnProperty(key) ) {
            ++length;
        }
    }
    return length;
}

var ObjectLength =
    Object.keys ? ObjectLength_Modern : ObjectLength_Legacy;

and as before, test it with:

console.log( ObjectLength(obj.Data) );

This code uses Object.keys(object).length in modern browsers and falls back to counting in a loop for old browsers.

But if you're going to all this work, I would recommend using Lo-Dash or Underscore instead and get all the benefits those libraries offer.

I set up a jsPerf that compares the speed of these various approaches. Please run it in any browsers you have handy to add to the tests.

Thanks to Barmar for suggesting Object.keys for newer browsers in his answer.

Community
  • 1
  • 1
Michael Geary
  • 26,814
  • 8
  • 56
  • 71
  • Using the conditional operator to do this kind of feature-detection seems overly complicated. – Paul Phillips Jun 07 '13 at 05:50
  • Hi, can you explain on this? Can I put this into a function and call whenever we need it? For safe precaution to users who use older browser, I will try to adopt this. – Bryan Learn Jun 07 '13 at 05:52
  • 1
    It's a pretty common way to do it, but fair enough, you could easily do the same thing with an if statement. The main thing is to do it outside the function instead of inside the function. – Michael Geary Jun 07 '13 at 05:52
  • @BryanLearn - This *is* a function. Leave out the `console.log()` calls and the end and you can use it as is. The `console.log()` calls illustrate how to call it. – Michael Geary Jun 07 '13 at 05:53
  • Thanks Michael, its abit complicated but I guess I will study on this. – Bryan Learn Jun 07 '13 at 06:04
  • I tried Object.keys(obj.Data) and it return 0,1,2 how can I get the total count or does it return in this format? – Bryan Learn Jun 07 '13 at 06:04
  • Bryan, call `ObjectLength(obj.Data)` – Michael Geary Jun 07 '13 at 06:07
  • I guess I have figured out. Thanks! – Bryan Learn Jun 07 '13 at 06:07
  • @BryanLearn - also check my updated answer. I think the simpler code at the top of the answer is the best way to go. It should certainly be easier to understand, and that's always a good thing. – Michael Geary Jun 07 '13 at 06:31
  • @BryanLearn - Another update! :-) Please check out my latest suggestion, which is to use either of the excellent libraries Lo-Dash or Underscore. I think you would find these very useful. If for any reason you can't use one of these, do note that I was wrong about the simple code being fastest - if you do include your own code from my answer, the best version of `ObjectLength()` is the one at the end of the latest update (include both the two separate functions and the `var ObjectLength = ...` after them). – Michael Geary Jun 07 '13 at 07:30
  • @PaulPhillips - thanks for the comment on the conditional operator. You were right! I updated the code so it should be easier to follow. It still uses the conditional operator, but in a much simpler way instead of all that nested stuff. – Michael Geary Jun 07 '13 at 07:32
  • Thank you @michaelGeary, you are awesome! I am using Underscore. It is so easy to use. – Bryan Learn Jun 07 '13 at 20:27
  • the latter would be better, for var obj1 = { 'test1': 123, 'test2': 456, length: 6 }, _.size(obj1) gives you 6 while _.keys(obj1).length gives you 3 (more accurate). – morph85 Jul 16 '18 at 08:03
  • You can also do ```values(object).length``` – Panayiotis Georgiou Oct 13 '20 at 07:20
84

In recent browsers you can use:

Object.keys(obj.Data).length

See MDN

For older browsers, use the for-in loop in Michael Geary's answer.

Barmar
  • 596,455
  • 48
  • 393
  • 495
  • Hi Barmar, somehow it does not log under console... Can you help me by explaining? – Bryan Learn Jun 07 '13 at 05:53
  • `keys` is not a property of the object to be counted. @BryanLearn: He meant `Object.keys(obj.Data).length`. Should be closed as a dupe anyway :-) – Bergi Jun 07 '13 at 05:54
  • To me this is the answer. Adding a library like lodash is not part of a solution. Also you can't rely on a `for in` loop to output in an expected order. – Ben Racicot Jan 13 '16 at 17:35
  • Much better answer. – Manachi Feb 18 '18 at 02:06
  • @BenRacicot If you only care about the length, why does the order matter? – Barmar Feb 18 '18 at 18:34
  • Looks like this works back to Internet Explorer 9 for anyone wondering, so unless you need to support really old browsers it should be fine – Kelly Barber Mar 09 '21 at 19:29
  • @KellyBarber The answer is 8 years old. `Object.keys()` was relatively new, and IE8 wasn't as prehistoric. – Barmar Mar 09 '21 at 20:21
36

Try Demo Here

var list ={}; var count= Object.keys(list).length;
Sudarshan
  • 3,159
  • 3
  • 21
  • 38
  • 5
    You rather should upvote other answers instead of re-posting the solutions :-) – Bergi Jun 07 '13 at 06:21
  • 6
    when i started making demo , no one had given this answer. – Sudarshan Jun 07 '13 at 06:27
  • 1
    @Bergi . You should look at timestamp before comments. Sometimes a better answer exists, but no one cares. – fendiSetiawan Mar 20 '20 at 11:44
  • @FendiSetiawan Looking at the timestamps, these are 7 year old comments on a closed question? (And even then, indeed Barmar's answer was posted, and edited, much earlier than this) – Bergi Mar 20 '20 at 11:56