Let's say I have this:
function arrSum(){
*code here*
}
How do I write the arrSum function such that it can sum all the integers within a multidimensional array (of variable depth).
I.e.
arrSum([2, 5, [4, 6], 5]) === 22;
I know there must be an answer to this somewhere but I really can't find it. If this is a duplicate please let me know.
Simply you can write a function like this with recursion
function arrSum(arr) {
var sum = 0;
// iterate array using forEach, better to use for loop since it have higher performance
arr.forEach(function(v) {
// checking array element is an array
if (typeof v == 'object')
// if array then getting sum it's element (recursion)
sum += arrSum(v);
else
// else adding the value with sum
sum += v
})
// returning the result
return sum;
}
console.log(arrSum([2, 5, [4, 6], 5]) === 22);
Using for
loop
function arrSum(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'object')
sum += arrSum(arr[i]);
else
sum += arr[i];
}
return sum;
}
console.log(arrSum([2, 5, [4, 6], 5]) === 22);
A more modern approach using .reduce()
:
const arr = [2, 5, [4, 6], 5];
const arrSum = array =>
array.reduce(
(sum, num) => sum + (Array.isArray(num) ? arrSum(num) : num * 1),
0
);
console.log(arrSum(arr));
Check this:
function arrSum(objArr){
var total = 0;
for(var outerLoop=0; outerLoop < objArr.length; outerLoop++){
if(objArr[outerLoop].constructor === Array){
for(var innerLoop=0; innerLoop < objArr[outerLoop].length; innerLoop++){
total += objArr[outerLoop][innerLoop];
}
} else {
total += objArr[outerLoop];
}
}
return total;
}
alert (arrSum([2, 5, [4, 6], 5]));
function arrSum(arr) {
var totalSum = null;
var numString = arr.toString();
var numberArray = numString.split(",");
numberArray.forEach(function(ele){
totalSum = totalSum + parseInt(ele);
});
return totalSum;
}
console.log(arrSum([2, 5, [4, 6], 5]);
If we have a multi-dimensional array with strings and integers and we have to get the sum of the numbers, then following @Pranav C Balan's solution we could add a check in the else loop to check only for digits as below -
function arrSum(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'object'){
sum += arrSum(arr[i]);
}else if (Number(arr[i])){
sum += arr[i];
}
}
return sum;
}
console.log(arrSum([2, 'a', 5, [4, 6, 10, [1, 2, 'b'], 10], 5]));
I would build a function similar to what Pranav C Balan with the difference that i would check the isObject()
before calling forEach()
,
This way i get around problems posed by sending a single numeric
parameter, or Null
values.
function arrSum(v) {
// checking if element is an array
if (typeof v == 'object') {
var sum = 0;
// iterate array using forEach, better to use for loop since it have higher performance
v.forEach(function(e) {
sum+=arrSum(e);
});
return sum;
}
else {
return v;
}
}
$('body').append($('<p></p>').html('[2, 5, [4, 6], 5] = ' + arrSum([2, 5, [4, 6], 5])));
$('body').append($('<p></p>').html('[2,, 5] = ' + arrSum([2,, 5])));
$('body').append($('<p></p>').html('5 = ' + arrSum(5)));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This can be done with lodash _.flattenDeep
and _.sum
:
var arr = [2, 5, [4, 6], 5];
arrSum(arr);
function arrSum(arr) {
var arrFlattens = _.flattenDeep(arr);
// => [2, 5, 4, 6, 5]
console.log(_.sum(arrFlattens));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>