1

(forgive me if I use slightly incorrect language - feel free to constructively correct as needed)

There are a couple posts about getting data from JSON data of siblings in the returned object, but I'm having trouble applying that information to my situation:

I have a bunch of objects that are getting returned as JSON from a REST call and for each object with a node of a certain key:value I need to extract the numeric value of a sibling node of a specific key. For example:

For the following list of objects, I need to add up the numbers in "file_size" for each object with matching "desc" and return that to matching input values on the page.

{"ResultSet":{

  Result":[

    {
        "file_size":"722694",
        "desc":"description1",
        "format":"GIF"
    },

    {
        "file_size":"19754932",
        "desc":"description1",
        "format":"JPEG"
    },

    {
        "file_size":"778174",
        "desc":"description2",
        "format":"GIF"
    },

    {
        "file_size":"244569996",
        "desc":"description1",
        "format":"PNG"
    },

    {
        "file_size":"466918",
        "desc":"description2",
        "format":"TIFF"
    }

  ]

}}
mflorida
  • 43
  • 1
  • 7

4 Answers4

1

You can use the following function:

function findSum(description, array) {
    var i = 0;
    var sum = 0;

    for(i = 0; i < array.length; i++) {
        if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
            sum += parseInt(array[i]["file_size"], 10);
        }
    }

    alert(sum);
}

And call it like this:

findSum("description1", ResultSet.Result);

To display an alert with the summation of all "description1" file sizes.

A working JSFiddle is here: http://jsfiddle.net/Q9n2U/.


In response to your updates and comments, here is some new code that creates some divs with the summations for all descriptions. I took out the hasOwnProperty code because you changed your data set, but note that if you have objects in the data array without the file_size property, you must use hasOwnProperty to check for it. You should be able to adjust this for your jQuery .each fairly easily.

var data = {};
var array = ResultSet.Result;

var i = 0;
var currentDesc, currentSize;
var sizeDiv;
var sumItem;

//Sum the sizes for each description
for(i = 0; i < array.length; i++) {
    currentDesc = array[i]["desc"];
    currentSize = parseInt(array[i]["file_size"], 10);

    data[currentDesc] =
        typeof data[currentDesc] === "undefined"
        ? currentSize
        : data[currentDesc] + currentSize;
}

//Print the summations to divs on the page
for(sumItem in data) {
    if(data.hasOwnProperty(sumItem)) {
        sizeDiv = document.createElement("div");
        sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
        document.body.appendChild(sizeDiv);
    }
}

A working JSFiddle is here: http://jsfiddle.net/DxCLu/.

Drew Gaynor
  • 8,292
  • 5
  • 40
  • 53
  • This one's close. How can I call this within a jQuery $.each function that I'm already using to do other stuff while looping? And how would I return the result to use for creating unique DOM elements for each "desc" type? – mflorida Oct 22 '12 at 20:21
  • This one works. Can you explain the code: data[currentDesc] = typeof data[currentDesc] === "undefined" ? currentSize : data[currentDesc] + currentSize; I'd just like to know what's going on for my own understanding. – mflorida Oct 23 '12 at 16:34
  • data[currentDesc] = typeof data[currentDesc] === "undefined" ? currentSize : data[currentDesc] + currentSize; Is it a shorthand for if/else? – mflorida Oct 23 '12 at 16:42
  • Have another question. I've updated the code to include another item in the original array - how could I display the total of each 'format' for each 'desc', like: **description1: 444MB (222MB JPEG, 222MB GIF)**? – mflorida Oct 23 '12 at 18:36
  • @mflorida: I'm using the [ternary (or conditional) operator](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Conditional_Operator), which as you suggested is similar to an if/else statement. When you say that you have another question, that is a perfect example of when it would be a good idea to create another entirely new question as I mentioned earlier. You can get help from many different people that way, instead of just one. – Drew Gaynor Oct 23 '12 at 20:50
0

That's an array embedded in an object, so

data.ResultSet.Result[2].file_size

would give you 778174

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • you just do a loop over the array, find whatever you want, and add up. – Marc B Oct 22 '12 at 17:18
  • I need to write out the result of EACH total for every "desc" and there are at least 10 different "desc" values in the 'real' data. So like: if "desc" matches "description1" add up all values and store in a hidden input field then if "desc" matches "description2" do the same. Sounds like I'm going to have to loop for each value of "desc" which itself varies coming from the server, which means finding those values, storing those in a new array then checking each item in the array for that value of "desc". – mflorida Oct 22 '12 at 17:33
  • Each dataset returned may have hundreds of items in the array, and there may be dozens of datasets to return from, so I'd rather not have to loop for each value of "desc". Can't I store the values in an array for each "desc" value then add those together? How do I create separate arrays for each "desc" and tell javascript to only put in matches? – mflorida Oct 22 '12 at 17:35
0
var sum = {}, result = ResultSet.Result

// Initialize Sum Storage
for(var i = 0; i < result.length; i++) {
  sum[result[i].desc] = 0; 
}

// Sum the matching file size
for(var i = 0; i < result.length; i++) {
  sum[result[i].desc] += parseInt(result[i]["file_size"]
}

After executing above code, you will have a JSON named sum like this

sum = {
  "description1": 20477629,
  "description2": 1246092
};
jwchang
  • 10,584
  • 15
  • 58
  • 89
  • `if( result[i].desc in sum ) sum[result[i].desc] += parseInt(result[i]["file_size"];` `else sum[result[i].desc] = parseInt(result[i]["file_size"];` All in one loop. – aziz punjani Oct 22 '12 at 17:24
  • Ahhh... That helps. Is there a way to do this if I'm already 'in' ResultSet.Result? Just use 'this'? – mflorida Oct 22 '12 at 17:37
0

An iterate like below should do the job,

var result =  data.ResultSet.Result;
var stat = {};
for (var i = 0; i < result.length; i++) {    
    if (stat.hasOwnProperty(result[i].cat_desc)) {       
        if (result[i].hasOwnProperty('file_size')) {
        stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);   
        }
    } else {
        stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
    }   
}

DEMO: http://jsfiddle.net/HtrLu/1/

Selvakumar Arumugam
  • 79,297
  • 15
  • 120
  • 134
  • Using 'hasOwnProperty' in the code I already may do the trick! Thanks! – mflorida Oct 22 '12 at 17:44
  • So 'hasOwnProperty' tells me if that property exists (which I know it will in the JSON I'm getting) - so how can I get/match the value of that specific property? – mflorida Oct 22 '12 at 20:24
  • @mflorida What do you mean by match.. to get simply use `[]` or `.` on the object.. like `data['file_size']` or `data.file_size` – Selvakumar Arumugam Oct 22 '12 at 20:26