HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Numerology Calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
numerologycalculatorstackoverflow

Problem

I've built the beginnings of a numerology calculator, and would like an experienced javascript developer to review this code.

It works as expected, but I can't help but think there is a better way to write it instead of using multiple for loops.

There are a few calculations that have to be made, so I can't see any way around it. Any direction would be great.

function addNumbers(arr, fn) {
    var arrayTotal = [],
    singleDigits = [];

    for (i = 0; i < arr.length; i++) {
        arrayTotal.push(
            fn(arr[i])
        );   
    }

    for (value in arrayTotal) {
        for (num in arrayTotal[value]) {
            singleDigits.push(parseInt(arrayTotal[value][num]));
        }
    }

    for (i = 0, sum = 0; i < singleDigits.length; i++) {
        sum += singleDigits[i];
    }

    for (i = 0, numericValue = 0, sum = fn(sum); i < sum.length; i++) {
        numericValue += parseInt(sum[i]);
    }

    return numericValue;
}

function splitNumbers(item) {
    return item.toString().split('');
}

var value = addNumbers([13, 11, 1938], splitNumbers);
document.body.innerHTML = value;

Solution

map and reduce are tailor made for problems like this.

To understand the while loop in the final version of the code at the bottom of this post, it may help to consider a "longhand" version that does the same thing:

// this sets the answer we seek to the sum of all the digits
// of every number passed in via the array
finalAnswer = addDigits(combinedDigits);

// but since this sum may still be larger than a 1 digit 
// number (ie, 10 or more), we need to continue the summing
// the digits until we end up with a single digit number
while ( finalAnswer > 9 ) {
  // this converts an integer to a string
  combinedDigits = '' + finalAnswer;
  // this sums the digits again
  finalAnswer = addDigits(combinedDigits);
}


Here's the final, complete version, with the more compact while loop. We are simply combining some of the steps above.

function addDigitsRecursively(arr) {

  var combinedDigits = arr.join(''), finalAnswer;

  while ( (finalAnswer = addDigits(combinedDigits)) > 9 )
    combinedDigits = '' + finalAnswer;

  function addDigits(str) {
    return str.split('').map(function(n) {return parseInt(n)})
                        .reduce(function(a, b){return a+b;})
  }

  return finalAnswer;
}

var value = addDigitsRecursively([13, 11, 1938]);
document.body.innerHTML = value;

Code Snippets

// this sets the answer we seek to the sum of all the digits
// of every number passed in via the array
finalAnswer = addDigits(combinedDigits);

// but since this sum may still be larger than a 1 digit 
// number (ie, 10 or more), we need to continue the summing
// the digits until we end up with a single digit number
while ( finalAnswer > 9 ) {
  // this converts an integer to a string
  combinedDigits = '' + finalAnswer;
  // this sums the digits again
  finalAnswer = addDigits(combinedDigits);
}
function addDigitsRecursively(arr) {

  var combinedDigits = arr.join(''), finalAnswer;

  while ( (finalAnswer = addDigits(combinedDigits)) > 9 )
    combinedDigits = '' + finalAnswer;

  function addDigits(str) {
    return str.split('').map(function(n) {return parseInt(n)})
                        .reduce(function(a, b){return a+b;})
  }

  return finalAnswer;
}

var value = addDigitsRecursively([13, 11, 1938]);
document.body.innerHTML = value;

Context

StackExchange Code Review Q#105427, answer score: 5

Revisions (0)

No revisions yet.