tags:

views:

145

answers:

3

Let me explain in detail. I have below an object with me -

{
    "OBJECT1" : {
        "NAME1" : "VALUE1",
        "NAME2" : "VALUE2",
        "NAME3" : "VALUE3"
     },
     "OBJECT2" : {
        "NAME4" : "VALUE4",
        "NAME5" : "VALUE5"
     }
}

From this object, I want to get something like number of elements in OBJECT1 = 3 and number of elements in OBJECT2 = 2. If at all this is possible using javascript. Basically what I am trying to do is, to loop through the name value pairs available in the object dynamically so that if someone adds another element to object, I don't have to change my code.

Also any alternative is also ruled out since I am allowed to only use object in my use-case.

+3  A: 

For JSON string that represent an object (which is your case), you cannot use any length property. you need to loop through the object (see Kristoffer S Hansen's answer).

If it represented an array, you could get the length with:

var len = arr.length;

JQuery makes it simpler:

var len = $(JSON).length;
Samuel_xL
No Jquery please and also I am supposed to avoid eval in my project standards.
Sachin Shanbhag
eval was for the array example, which you don't need anyway. It was just additional information :) Ok I've removed eval since it's off-topic.
Samuel_xL
Don’t use `eval` if not necessary.
Gumbo
Currently, my JSON object is just NAME VALUE pairs as in the example above. I am not sure if looping thru all elements in object is possible or not. just in case its not possible, then maybe I need to move NAME VALUE pairs into an array from where I can use the length and loop through.
Sachin Shanbhag
+1  A: 

To answer your broader goal, as specified in your question:

For looping through the properties, you can use the for..in construct:

for (var item in myobject) {
  // some browsers add more properties to every object, we don't want those
  if (myobject.hasOwnProperty(item)) {
    do_something(item);
  }
}

Assuming that myobject is the object in your question, this will loop through it and call do_something(OBJECT1) and do_something(OBJECT2); you can use the same construct to loop through the child objects:

// loop through OBJECT1 and OBJECT2
for (var item in myobject) {
  // some browsers add more properties to every object, we don't want those
  if (myobject.hasOwnProperty(item)) {
    // loop through the item's children
    for (var pair in item) {
      if (item.hasOwnProperty(pair)) {
        // each of the name:value pairs will be passed to this
        do_something_else(item,pair);
      }
    }
  }
}
Piskvor
In the second snippet it seems that `item` is already the *key* of each key-value pair, so it makes no sense to iterate over it again...
Timwi
@Timwi: Actually, no: in the outer loop, we iterate over the top-level properties, i.e. OBJECT1 and OBJECT2. In the inner loop, we iterate over *their* properties, i.e. NAME1,NAME2,NAME3, and NAME4, NAME5, respectively. If the nesting went further, we could be iterating over the deeper objects (maybe recursion could be used).
Piskvor
To clarify, in the second loop I'm iterating the properties of a property of the top-level object (`myobject.OBJECT1.NAME1` etc). This nesting could go deeper, but doesn't in this case.
Piskvor
Yeah, sorry, for some reason I thought your second snippet was the `do_something` function the first one called inside the loop. Never mind :)
Timwi
+4  A: 

Without converting your object you could iterate through the object counting properties like so:

function countObjectProperties(obj)
{
    var count = 0;
    for(var i in obj)
        if(obj.hasOwnProperty(i))
            count++;

    return count;
}

Expanding on why you need to use hasOwnProperty as I said in the comment below you can run into an issue where a library or browser has added methods and properties to Objects, in order to avoid counting these we check for hasOwnProperty before counting it. More details at MSDN or at Mozilla Developer Center

Kristoffer S Hansen
why is hasOwnProperty necessary (just asking) ?
Samuel_xL
Awesome, this works fine for me. Thanks a lot.
Sachin Shanbhag
@Samuel_xL You need hasOwnProperty to avoid counting functions, and other unwanted builtins the the browser and/or plugins might have added.
Kristoffer S Hansen
thanks for the info
Samuel_xL