I have been struggling with this problem the whole day.
I have got the following array:
controller.array = [{
Equity: "0",
Bond: "97.42",
Cash: "67.98"
}, {
Equity: "5.32",
Bond: "13.12",
Cash: "8"
}, {
// ...
} /* ... */ ]
What I want to do is create a single array containing objects with combined values like so:
controller.newArray = [{
Type: "Equity",
Percentage: "5.32"
}, {
Type: "Bond",
Percentage: "110.54"
}, {
Type: "Cash",
Percentage: "75.98"
} /* ... */ ]
I have tried using _.each like this:
.map(function(item, value) {
var array = [];
_.each(item, function(value, item) {
array.push({
'Source': item,
'Percentage': value
})
})
return array;
})
.value()
What then happens is that it returns an array, containing multiple arrays with objects with my values. Now my problem is that I cant seem to combine all the arrays that are being returned.
Any ideas? Please?
You can transpose the array of objects into an array of values grouped by their common key.
Then you can map the values over to the resulting objects.
The transpose() and sum() functions are underscore mixins, so you can chain them!
_.mixin({
transpose : function(array) {
return _.chain(array).map(_.keys).flatten().uniq().reduce(function(result, key) {
result[key] = _.pluck(array, key);
return result;
}, {}).value();
},
sum : function(values) {
return _.reduce(values, function(sum, value) {
return sum + (_.isNumber(value) ? value : parseFloat(value));
}, 0);
}
});
var array = [{
Equity: "0",
Bond: "97.42",
Cash: "67.98"
}, {
Equity: "5.32",
Bond: "13.12",
Cash: "8"
}];
var result = _.chain(array).transpose().map(function(value, key) {
return {
Type: key,
Percentage: _.sum(value).toFixed(2)
};
}).value();
console.log(JSON.stringify(result, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
One way, using only JavaScript could be to use map and reduce functions:
var data = [{Equity: "0", Bond: "97.42", Cash: "67.98"},
{Equity: "5.32", Bond: "13.12", Cash: "8"}];
var sumMap = data.reduce(function(acc, item) {
Object.keys(item).forEach(function(itemKey) {
if (acc[itemKey] === undefined) {
acc[itemKey] = 0;
}
acc[itemKey] += parseFloat(item[itemKey]);
});
return acc;
}, {});
var result = Object.keys(sumMap).map(function(itemKey) {
return {
"Type": itemKey,
"Percentage": "" + sumMap[itemKey]
};
});
console.log(JSON.stringify(result, null, 2));
The intermediate result sumMap will be something like this:
{
Equity: 5.32,
Bond: 110.54,
Cash: 75.98
}
The fiddle (thanks to CPHPython).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With