0

I'm putting together some JavaScript that'll be pulling in multiple JSON files whose data will be used in graphs. Ultimately, I need to identify when I've reached the absolute end of an associative array being processed in an $.each() loop (jQuery is involved) in order to trigger the next JSON file. I've bumped into various solutions for a one-tiered object...but what about a MULTI-TIERED object? How does the last row in the last column know it's the LAST?

Here's an example JSON I'm working with:

{
    "Network":{
        "Hardware":262464,
        "Software":53016,
        "Internal Personnel":440202,
        "External Personnel":188658,
        "Outside Services":1344100,
        "Facilities and Overhead":16172,
        "Other":92588,
        "Total":2397200
    },
    "Wide Area Network":{
        "Hardware":75600,
        "Software":18900,
        "Internal Personnel":132300,
        "External Personnel":56700,
        "Outside Services":315000,
        "Facilities and Overhead":6300,
        "Other":25200,
        "Total":630000
    }
}

Here's a rough idea of a loop I'm running on that JSON

function buildColumns(array, parent) {
    $.each(array, function(key, value) {
        var newParent = $('<column>'); 
        $('<columnBox>').append($('<h2>').html(key)).append(newParent).appendTo(parent);
        if(value instanceof Object) buildColumns(value, newParent);     
    });
}

The loop is pseudo-recursive, as you can see, and may not ultimately be what I use. But there you go.

rink.attendant.6
  • 36,468
  • 57
  • 89
  • 143
  • 1
    I don't really understand what the problem is. Are you saying your JS code does not work? – Explosion Pills Aug 23 '13 at 17:24
  • before your $.each get the length of the object/array with .length, then when you are looping through inside the $.each, you can get the length of each subarray/tier and repeat the process until the index returned from $.each matches the length :) – A.O. Aug 23 '13 at 17:25
  • @A.O. you should move your comment to answer. – Jack Thor Aug 23 '13 at 17:26
  • @ExplosionPills: The javascript works fine. I just need to amend it with the ability to identify the absolute last item in a multi-dimensional object. As it turns out, objects don't inherently possess the same discoverable characteristics as simple arrays. Getting at information like a sub-array's length, or selecting an item by its numeric index when it has text-based keys, is more elusive. Those darn object don't WANT to be arrays, the little buggers! – Mark Kanning Aug 23 '13 at 17:47
  • There is no such thing as an associative array in JS. JSON is a string with a different specification than a JS object, which happens to look like JSON. When it comes to tabular data, the typical approach is to use an array of ordered headers per row and a second array of row data objects. Iterate the row data, then for each row, iterate the headers array and emit the cell data by indexing into the row object for that column (header). Basically, I'm advocating rethinking your design and data structures such that you won't need to worry about object ordering (even if it's guaranteed nowadays). – ggorlen May 21 '21 at 00:06

2 Answers2

1

You can find out how many items are in an array with the length property.

So in your example array.length will return the number of items. That's assuming the passed variable is an array.

The way you can do this for objects is:

Object.keys(jsonObject).length

Also, because I wasn't exactly sure if it was the array or object you are trying to find the length off, you can use the code below to add a count method to an object to find how many children it has:

Object.prototype.count = function() {
  oCount = 0; 
  for(var curObj in this) 
    if(curObj.hasOwnProperty(prop)) oCount++; 
  return oCount;
};

To be used as such:

console.log(jsonObject.count());
Mark
  • 2,076
  • 1
  • 13
  • 25
  • My understanding (ignorance revealing itself) is that .length doesn't work on objects, only arrays. I bumped into that roadblock earlier, too. – Mark Kanning Aug 23 '13 at 17:38
  • Sorry I misunderstood your question. I have edited my post :) – Mark Aug 23 '13 at 17:39
  • 1
    Make sure to check if the property exist on the object with hasOwnProperty. Otherwise it's possible you get wrong count results because it can also get the properties in the prototype chain. – Wim Mostmans Aug 23 '13 at 17:47
  • Thanks for that Wim, I wrote that very quickly. Edited my post to reflect your advice. – Mark Aug 23 '13 at 17:51
  • 1
    I really wouldn't extend `Object.prototype`. What if I had `var x = {count: 2}`? – Rocket Hazmat Aug 23 '13 at 17:54
-1

The order of fields of JavaScript objects is not guaranteed to be consistent. Neither over time nor between different browsers. See here: Does JavaScript Guarantee Object Property Order?

So the last item is not always the same.

If you want to have the last item, you need to rework your object into an array.

{
    "Network": [
         [{"Hardware":262464}],
         [{"Software":53016}],
         //  ...
    ],
    "Wide Area Network":[
        [{ "Hardware":75600}],
        // ...
    ],
    // ...
}

He

Community
  • 1
  • 1
yunzen
  • 30,001
  • 10
  • 64
  • 93
  • I thought of converting the JSON into arrays, but the text-based key for the value wouldn't carry over. I'd need to have another array just to associate keys to values. That would start to get unwieldy. This would be SOOOOO easy in PHP. *sigh* – Mark Kanning Aug 23 '13 at 18:01