-3

I have saved my JSON object in a variable and I am making calculations off of the properties within the object; however, I am finding that the calculations are very long to write and if the data becomes larger, the calculations can become pretty long.

I am hoping that there is a simpler way to make calculations than how I am currently doing it.

Here is the JSON data saved within a javascript file:

var obj = {
  "Open": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":6,
    "Sprint_6":38,
    "Sprint_7":7
  }],
  "Design": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":null,
    "Sprint_6":1,
    "Sprint_7":null
  }],
  "Requirement": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":1,
    "Sprint_6":1,
    "Sprint_7":null
  }],
  "Ready_for_Build": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":4,
    "Sprint_6":2,
    "Sprint_7":null
  }],
  "Build": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":12,
    "Sprint_6":1,
    "Sprint_7":null
  }],
  "Ready_for_Test": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":4,
    "Sprint_6":4,
    "Sprint_7":null
  }],
  "Test": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":5,
    "Sprint_6":6,
    "Sprint_7":null
  }],
  "Ready_for_Acceptance": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":null,
    "Sprint_5":3,
    "Sprint_6":null,
    "Sprint_7":null
  }],
  "Accepted": [{
    "Sprint_2":38,
    "Sprint_3":43,
    "Sprint_4":57,
    "Sprint_5":19,
    "Sprint_6":null,
    "Sprint_7":null
  }],
  "Total_Bugs": [{
    "Sprint_2":47,
    "Sprint_3":39,
    "Sprint_4":71,
    "Sprint_5":39,
    "Sprint_6":null,
    "Sprint_7":null
  }],
  "Bugs_Success": [{
    "Sprint_2":37,
    "Sprint_3":25,
    "Sprint_4":42,
    "Sprint_5":11,
    "Sprint_6":null,
    "Sprint_7":null
  }],
  "Bugs_In_Progress": [{
    "Sprint_2":null,
    "Sprint_3":null,
    "Sprint_4":7,
    "Sprint_5":4,
    "Sprint_6":null,
    "Sprint_7":null
  }]
};

Here is a calculation I am using to sum the numbers in various keys:

var totDone = obj.Ready_for_Test[0].Sprint_2 + obj.Ready_for_Test[0].Sprint_3 + obj.Ready_for_Test[0].Sprint_4 + obj.Ready_for_Test[0].Sprint_5 + obj.Ready_for_Test[0].Sprint_6 + obj.Ready_for_Test[0].Sprint_7 +
    obj.Test[0].Sprint_2 + obj.Test[0].Sprint_3 + obj.Test[0].Sprint_4 + obj.Test[0].Sprint_5 + obj.Test[0].Sprint_6 + obj.Test[0].Sprint_7 +
    obj.Ready_for_Acceptance[0].Sprint_2 + obj.Ready_for_Acceptance[0].Sprint_3 + obj.Ready_for_Acceptance[0].Sprint_4 + obj.Ready_for_Acceptance[0].Sprint_5 + obj.Ready_for_Acceptance[0].Sprint_6 + obj.Ready_for_Acceptance[0].Sprint_7 +
    obj.Accepted[0].Sprint_2 + obj.Accepted[0].Sprint_3 + obj.Accepted[0].Sprint_4 + obj.Accepted[0].Sprint_5 + obj.Accepted[0].Sprint_6 + obj.Accepted[0].Sprint_7;
    console.log(totDone); 

If my JSON data expands, in order to do further calculations, my algorithm will become very lengthy. Is there a simpler way to run calculations on the data?

  • 1
    This doesn't seem to have anything to do with JSON ? – adeneo Feb 08 '16 at 20:30
  • 5
    I take it you haven't learned about [loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration)? – Patrick Evans Feb 08 '16 at 20:30
  • I'm assuming you are already parsing your JSON at some point before your calculation? Then it is really just an question of how to iterate over object properties. Have a look on SO for that. http://stackoverflow.com/questions/684672/loop-through-javascript-object – Simon Merrick Feb 08 '16 at 20:33
  • @Jesse Kernaghan - I don't see how that will work. Array.prototype.reduce() operates on arrays not objects. Not a good fit for this problem. – Simon Merrick Feb 08 '16 at 20:37
  • @SimonMerrick fortunately we have methods such as Object.keys() which would give us an... array that we can use to extract data from the object. – Kevin B Feb 08 '16 at 20:39
  • Also @justinrian, any reason why every object is wrapped in an array? – Simon Merrick Feb 08 '16 at 20:39
  • Every object was wrapped in an array because without wrapping them in an array, the console gives me an error when trying to do calculations. Is there any way around not wrapping them in an array? - @SimonMerrick – justinrian Feb 08 '16 at 21:38
  • 1
    @justinrian Don't wrap them in an array, and leave out `[0]` in the calculation. `obj.Ready_for_Test.Sprint_2`. – Barmar Feb 08 '16 at 21:43
  • 1
    You should probably change all the `Sprint_#` properties into a single `Sprints` array. – Barmar Feb 08 '16 at 21:45
  • I'm I the only one worried by the key names of that object? I so very much hope it's a random example. This is some truly scary stuff. – Jonathan Feb 08 '16 at 23:30

3 Answers3

0

You can call getSum like this

var answer = getSum(obj, 'Test');
console.log(answer);

function getSum(data, key){
    var sprints = data[key][0];
    var sum = 0;
    for (var sprint in sprints){
         if(sprints[sprint]){
              sum += sprints[sprint];
         }
    }
    return sum;
}

and to get total of all

 var total = 0;
 for (var key in obj){

      total += getSum(onj, key);
 }

console.log(total);

if you just want to add some specific sprint values, then you need to pass a list of those sprint names like

function getSum(data, key, sprintNames){
    var sprints = data[key][0];
    var sum = 0;
    sprintNames.forEach(function(name){
        if(sprints[name]){
              sum += sprints[name]
         }
    });
    return sum;
}

getSum(obj, 'Design', ['Sprint_2', 'Sprint_3']);
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • @PatrickEvans I am not using `for in` with arrays , I am using it with `Object`. In my code `for (var sprint in sprints)`, sprints is an objects with different sprint keys – Zohaib Ijaz Feb 08 '16 at 20:43
  • @ZohaibIjaz What if the I only want to add certain sprints and not all sprints within one of the keys? (Ex: Data = obj | Key = Test; but I only want to add Sprint_5 and Sprint_6? How can i identify the specific properties within the key to sum?) – justinrian Feb 09 '16 at 03:48
  • @justinrian I modified my answer as you said, I hope it will work – Zohaib Ijaz Feb 09 '16 at 08:41
  • @ZohaibIjaz Thanks for your response. I am getting the following message in the console when I attempt to add specific sprint values: Uncaught TypeError: sprintNames.forEach is not a function. Thanks again – justinrian Feb 09 '16 at 15:01
  • Then you are not calling correctly, third parameter is a an array of sprint names – Zohaib Ijaz Feb 09 '16 at 15:08
  • Worked like a charm. Thank you for all your help. @ZohaibIjaz – justinrian Feb 09 '16 at 15:12
0

Assuming you just want to sum up all non-null values in that JSON, here's a simple solution with for loops: https://jsfiddle.net/vgpw4h1h/1/

var sum = 0;
for (status in obj) {
  for (project in obj[status]) {
    for (sprint in obj[status][project]) {
      sum += obj[status][project][sprint];
    }
  }
}
console.log('Points from all sprints: ' + sum);
alumarcu
  • 133
  • 6
0

Firstly, data structure is important. Combining all of the suggestions in the comments section and my own experience, I would suggest structuring the data as follows.

// Your JavaScript Object
var backlog = {
    Open: [
        null, null, null,
        6, 38, 7
    ],
    Design: [
        null, null, null,
        null, 1, null
    ],
    Requirement: [
        null, null, null,
        1, 1, null
    ],
    Ready_for_Build: [
        null, null, null,
        4, 2, null
    ],
    Build: [
        null, null, null,
        12, 1, null
    ],
    Ready_for_Test: [
        null, null, null,
        4, 4, null
    ],
    Test: [
        null, null, null,
        5, 6, null
    ],
    Ready_for_Acceptance: [
        null, null, null,
        3, null, null
    ],
    Accepted: [
        38, 43, 57,
        19, null, null
    ],
    Total_Bugs: [
        47, 39, 71,
        39, null, null
    ],
    Bugs_Success: [
        37, 25, 42,
        11, null, null
    ],
    Bugs_In_Progress: [
        null, null, 7,
        4, null, null
    ]
};

First note how greatly fewer syntactical characters ({, }, [, ], :, ', and ") are required. This isn't necessarily an indicator of code quality but in this case it also greatly simplifies the next set of code.

To get your sums you can use functions such as Array.prototype.reduce() and Array.prototype.map() to iterate over the data and perform powerful calculations with minimal repetition.

// A collection of the stages that you want to add up
var postDevBacklogStages = [
    backlog.Ready_for_Test,
    backlog.Test,
    backlog.Ready_for_Acceptance,
    backlog.Accepted
];

// A helper funnction to find the sum of an array
var sumArray = function (array){
    return array.reduce(function(previousValue, currentValue, currentIndex, array){
    if (typeof(currentValue) != "number") {
        return previousValue;
    } else {
      return previousValue + currentValue;
    }
  });
};

// Finds the sums of the arrays for each stage you want to add up
var postDevBacklogStageSums = postDevBacklogStages.map(function(currentValue, index, array){
    return sumArray(currentValue);
});

// Finds the sum of the sums of stages
var sumTotal = sumArray(postDevBacklogStageSums);

console.log(postDevBacklogStageSums); // [8, 11, 3, 157]
console.log(sumTotal); // 179
Simon Merrick
  • 732
  • 4
  • 13