Let's say that I have an array of arrays, like so:
[ [0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3] ]
How do I generate a new array that sums all of the values at each position of the inner arrays in javascript? In this case, the result would be: [17, 10, 19]. I need to be able to have a solution that works regardless of the length of the inner arrays. I think that this is possible using some combination of map and for-of, or possibly reduce, but I can't quite wrap my head around it. I've searched but can't find any examples that quite match this one.
If you want to sum all the elements between two indexes, you can use a simple index based for loop. let start = 1, end = 3, sum = 0; for(let i = start; i <= end; i++) sum += array[i]; slice and reduce can also be used: let sum = array.
join() The join() method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.
The idea is to start traversing both the array simultaneously from the end until we reach the 0th index of either of the array. While traversing each elements of array, add element of both the array and carry from the previous sum. Now store the unit digit of the sum and forward carry for the next index sum.
You can use Array.prototype.reduce()
in combination with Array.prototype.forEach()
.
var array = [ [0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3] ], result = array.reduce(function (r, a) { a.forEach(function (b, i) { r[i] = (r[i] || 0) + b; }); return r; }, []); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Update, a shorter approach by taking a map for reducing the array.
var array = [[0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3]], result = array.reduce((r, a) => a.map((b, i) => (r[i] || 0) + b), []); console.log(result);
Using Lodash 4:
function sum_columns(data) { return _.map(_.unzip(data), _.sum); } var result = sum_columns([ [1, 2], [4, 8, 16], [32] ]); console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Lodash 4 has changed the way _.unzipWith
works, now the iteratee gets all the values passed as spread arguments at once, so we cant use the reducer style _.add
anymore. With Lodash 3 the following example works just fine:
function sum_columns(data) { return _.unzipWith(data, _.add); } var result = sum_columns([ [1, 2], [4, 8, 16], [32], ]); console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
_.unzipWith
will insert undefined
s where the row is shorter than the others, and _.sum
treats undefined values as 0. (as of Lodash 3)
If your input data can contain undefined
and null
items, and you want to treat those as 0, you can use this:
function sum_columns_safe(data) { return _.map(_.unzip(data), _.sum); } function sum_columns(data) { return _.unzipWith(data, _.add); } console.log(sum_columns_safe([[undefined]])); // [0] console.log(sum_columns([[undefined]])); // [undefined]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
This snipet works with Lodash 3, unfortunately I didn't find a nice way of treating undefined as 0 in Lodash 4, as now sum is changed so _.sum([undefined]) === undefined
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