Using for..in to iterate object and reduce to iterate array
var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}];
var result = [data.reduce((acc, n) => {
for (var prop in n) {
if (acc.hasOwnProperty(prop)) acc[prop] += n[prop];
else acc[prop] = n[prop];
}
return acc;
}, {})]
console.log(result)
Answer from Chris Li on Stack OverflowUsing for..in to iterate object and reduce to iterate array
var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}];
var result = [data.reduce((acc, n) => {
for (var prop in n) {
if (acc.hasOwnProperty(prop)) acc[prop] += n[prop];
else acc[prop] = n[prop];
}
return acc;
}, {})]
console.log(result)
Use Lodash to simplify your life.
const _ = require('lodash')
let keys = ['costOfAirtickets', 'costOfHotel'];
let results = _.zipObject(keys, keys.map(key => _.sum( _.map(data, key))))
...
{ costOfAirtickets: 4000, costOfHotel: 2200 }
Explanation:
_.sum(_.map(data, key)): generates sum of each array_.zipObject: zips the results with the array sum- using
keys.map()for sum of each key as_.mapdoes not guarantee order.
Documentation:
- sum: https://lodash.com/docs/4.17.10#sum
- zipObject: https://lodash.com/docs/4.17.10#zipObject
- map: https://lodash.com/docs/4.17.10#map
Try:
sum += parseInt($scope.logs[i].intTime);
Instead of:
sum += $scope.logs[i].intTime;
EDIT: I would recommend you have a look at reduce function, which is the javascript way of looping on your array in this case: https://www.w3schools.com/jsref/jsref_reduce.asp
EDIT2: You initialize $scope.logs.intTime to "". This first value stays in your array and generates NaN.
I suggest you initialize your array like this:
$scope.logs = [];
The intTime is defined in your object as String. So when you are doing the sum, it is actually doing a string concatenation. Convert to Number using pasrseInt and do the sum.
Your question is more general javascriptthan angular
You can sum element of array by using the Array.reduce function
You can sum on a specific status by filtering first
Ie
const sum = this.data.filter(item => item.status === 'settled')
.reduce((acc, item) => acc + Number(item.claimed_value), 0);
Note that as said in comment you received a string and not a numberso you must convert it at first (see the Number() function in thereduceclosure)) otherwise the+` operator will just concatenate the string
let finalSum = 0;
this.data.forEach((item) => {
if(item.status === 'settled'){
finalSum += item.claimed_value
}
});
console.log("final sum is ", finalSum);
Hello, This will loop on all the arrays in your data list , and add the number of claimed_value to the finalSum .
Hope this will work for you.
Use Array#Reduce:
// Array of numbers
var array = [1,2,3,4,5];
var sum = array.reduce((acc, cur) => acc + cur, 0);
console.log(sum)
// Array of strings
var toNumber = ['1','2','3','4','5'];
var sumNumber = toNumber.reduce((acc, cur) => acc + Number(cur), 0)
console.log(sumNumber);
let sum = array.reduce(function (acc, cur) { return acc + cur; });
In your current implementation you basically iterate over all items within the items array and return the objects mediaShare property.
this.totalCount = this.items.map((item)=> item.mediaShare); // => ["123", "345", ...]
What you actually want to do is to get the sum of all these values.
Considering the values inside totalCount are now a collection of strings that seem to hold a numeric value, you can do the following:
this.totalCount = this.items.map((item)=> Number.parseInt(item.mediaShare)).reduce((acc, curr) => acc + curr, 0); // Or `parseFloat`, if your values might be of type float
Read up on Array.prototype.reduce to learn how it behaves.
try this
let totalVal;
for(let i = 0; i < this.totalCount.length; i++) {
totalVal = totalVal + parseInt(this.totalCount[i]);
}
Here you go:
const data={
2:{3:"3514.80", 4:"7259.32"},
5:{6:"864941.86", 7:"1076976.54"},
8:{"":"14145.69"},
9:{10:"223835.02", 11:"60978.31", 12:"5554.92"}
}
const result = Object.values(data).map(items => Object.values(items).map(val => Number(val)).reduce((a,b) => a + b, 0))
console.log(result)
You could use the funcitons Object.values() and Array reduce in combination. Try the following
var totalByLevel = {
2: {
3: '3514.80',
4: '7259.32'
},
5: {
6: '864941.86',
7: '1076976.54'
}
};
var sum = Object.values(totalByLevel).reduce((acc, curr) => {
acc.push(String(Object.values(curr).reduce((a, c) => a + Number(c), 0)));
return acc;
}, []);
console.log(sum);
The correct way of using JavaScript's reduce function (which is also valid for TypeScript) would be:
const response = {
"carts": {
"value": [
{
"Amt": 40
},
{
"Amt": 20.25
},
{
"Amt": 10.30
}
]
}
};
const total = response.carts.value.reduce((sum, item) => sum + item.Amt, 0);
console.log(total);
Note that if you want to support IE8 you have to include a polyfill (like that on MDN's page).
I am very much in favor of the Rxjs' Observable answer, but since no one else mentioned it : Javascript arrays have a reduce function, so one can use it in Typescript too !
// suppose variable carts already stores the deserialized json
let total: number = carts.value.reduce(
(a: number, b) => a + b.Amt, 0);
after @Stefan's comments :
Fixed mistakes & better to not assign type of b, so that it will be inferred from the context and maybe raise a Typescript error at compile-time.