0

I have a JSON response like below:

[
{"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}],
{"name": "b", "data": [{"value":10,"id":1},{"value":20,"id":2}],
{"name": "c", "data": [{"value":10,"id":1},{"value":20,"id":2}],
{"name": "d", "data": [{"value":10,"id":1},{"value":20,"id":2}],
{"name": "e", "data": [{"value":10,"id":1},{"value":20,"id":2}],
]

How to sum each "value" inside each element of data (column wise) and get the result like:

[{"name": "something", "data":[{"value":50,"id":1},{"value":100,"id":2}]

How to use array.reduce() for this or is there any other method to achieve the above result?

4
  • 2
    Your JSON is invalid. Commented May 24, 2018 at 11:22
  • does data have always the same id on the same index? Commented May 24, 2018 at 11:23
  • 7
    You spec is not clear. We can understand how to reduce values by id, but your given suggested result is not clear about the "name" key... Do you want to reduce the names? Commented May 24, 2018 at 11:24
  • the final result you want is the some of values based on their id's?? so you should look for [{"value":50,"id":1},{"value":100,"id":2}] not for name. Commented May 24, 2018 at 11:30

5 Answers 5

2

Try out the following logic.

var series = [{"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}]}, ... , ....]

var resultSeries = series.reduce((acc, cur) => {
    var result = {
        name: ‘Something’,
        data: []
    };
    var dataArray = acc.data.map((el, i) => {
        var curData = cur.data[i] || {};
        var sum = (el.value || 0) + (curData.value || 0);
        return {
            value: sum
        }
    });
    result.data = dataArray ;
    return result;
})

now resultSeries will hold

[{"name": "something", "data":[{"value":50,"id":1},{"value":100,"id":2}]
Sign up to request clarification or add additional context in comments.

Comments

1

You could take an object as hash table for the id and sum the values.

var array = [{ name: "a", data: [{ value: 10, id: 1 }, { value: 20, id: 2 }] }, { name: "b", data: [{ value: 10, id: 1 }, { value: 20, id: 2 }] }, { name: "c", data: [{ value: 10, id: 1 }, { value: 20, id: 2 }] }, { name: "d", data: [{ value: 10, id: 1 }, { value: 20, id: 2 }] }, { name: "e", data: [{ value: 10, id: 1 }, { value: 20, id: 2 }] }],
    result = { name: 'something', data: Object.values(array.reduce((r, { data }) => {
        data.forEach(({ value, id }) => {
            r[id] = r[id] || { value: 0, id };
            r[id].value += value;
        });
        return r;
    }, Object.create(null))) };

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

Try this code

<script>
 var numbers = [
{"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
{"name": "b", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
{"name": "c", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
{"name": "d", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
{"name": "e", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
];

function getSum(total, val) {
  total.data[0].value = total.data[0].value + val.data[0].value;
  total.data[1].value = total.data[1].value + val.data[1].value;
  return total;
 }
function myFunction(item) {
   document.getElementById("demo").innerHTML = 
  JSON.stringify(numbers.reduce(getSum));
}

This prints

Sum of numbers in array: {"name":"a","data":[{"value":50,"id":1},{"value":100,"id":2}]}

The code just adds the values on each iteration and updates the existing value.

Comments

0

Use Array.reduce and Array.map

var arr =[{"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}]},{"name": "b", "data": [{"value":10,"id":1},{"value":20,"id":2}]},{"name": "c", "data": [{"value":10,"id":1},{"value":20,"id":2}]},{"name": "d", "data": [{"value":10,"id":1},{"value":20,"id":2}]},{"name": "e", "data": [{"value":10,"id":1},{"value":20,"id":2}]}];

var result = {
   "name" : "something",
   "data" : arr.reduce((a,c) => { // reduces/merges 2 records of arr
      a.data.map((v, i) => { // add values for the 2 records (column wise)
        v.value = v.value + c.data[i].value;
        return v;
      });
      return a;
   })
};
console.log(result);

Comments

0

I believe your JSON data looks like what I've used in the below snippet. You could do this:

    a = [
    {"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
    {"name": "b", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
    {"name": "c", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
    {"name": "d", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
    {"name": "e", "data": [{"value":10,"id":1},{"value":20,"id":2}]},
    ]
    
    let reducer = (accumulator, currValue) => {
            accumulator.name = "something";
        	for (let i = 0; i < accumulator.data.length; i++) {
        			accumulator.data[i].value += currValue.data[i].value;
            }
            return accumulator
        };

    // This will give the result you want:

    console.log(a.reduce(reducer));

The result will be:

{"name":"something","data":[{"value":50,"id":1},{"value":100,"id":2}]}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.