MrJonesIsMe
MrJonesIsMe

Reputation: 39

Javascript summing numbers from strings nested in array

I have been tasked with creating a function that has a single argument for an input. This argument is an array containing credit card number strings with hyphens included. The function must output the credit card number with the greatest sum of digits. If two credit card numbers have the same sum, then the last credit card number should be returned. Here is an example of the nested array.

['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260']

Below is what I have tried. Any and all suggestions are appreciated. Thanks!

function creditSum(creditCardNumber) {
      var number1= creditCardNumber[0];
      var number2= creditCardNumber[1];
      var number3= creditCardNumber[2];
      var number4= creditCardNumber[3];
      var split1=[];
      var split2=[];
      var split3=[];
      var split4=[];
       split1= number1.split ('');
       split2= number2.split ('');
       split3= number3.split ('');
       split4= number4.split ('');
      var sum1= split1[0]+split1[1]+split1[2]+split1[3]+split1[5]+split1[6]+split1[7]+split1[8]+split1[10]+split1[11]+split1[12]+split1[13]+split1[15]+split1[16]+split1[17]+split1[18];
      var sum2= split2[0]+split2[1]+split2[2]+split2[3]+split2[5]+split2[6]+split2[7]+split2[8]+split2[10]+split2[11]+split2[12]+split2[13]+split2[15]+split2[16]+split2[17]+split2[18];
      var sum3= split3[0]+split3[1]+split3[2]+split3[3]+split3[5]+split3[6]+split3[7]+split3[8]+split3[10]+split3[11]+split3[12]+split3[13]+split3[15]+split3[16]+split3[17]+split3[18];
      var sum4= split4[0]+split4[1]+split4[2]+split4[3]+split4[5]+split4[6]+split4[7]+split4[8]+split4[10]+split4[11]+split4[12]+split4[13]+split4[15]+split4[16]+split4[17]+split4[18];
      if (sum1>sum2 && sum1>sum3 && sum1>sum4){
        answer= number1;
      }
      else if (sum2>sum1 && sum2>sum3 && sum2>sum4){
        answer= number2;
      }
      else if (sum3>sum1 && sum3>sum2 && sum3>sum4){
        answer=number3;
      }
      else if (sum4>sum1 && sum4>sum2 && sum4>sum3){
        answer=number4;
      }
      else if (sum1==sum2){
        answer=number2;
      }
        else if (sum1==sum3){
          answer=sum3;
        }
        else if (sum1==sum4){
          answer=sum4;
        }
        else if (sum2==sum3){
          answer=sum3;
        }
        else if (sum2==sum4){
          answer=sum4;
        }
        else if (sum3==sum4){
          answer=sum4;
        }
        return answer

    }

Upvotes: 1

Views: 147

Answers (8)

trincot
trincot

Reputation: 350137

You could use this ES6 function:

function cardWithMaxSum(creditCardNumbers) {
    return creditCardNumbers.reduce( (best, card) => {
        let sum = card.match(/\d/g).reduce( (a,b) => +a + +b );
        return sum >= best[0] ? [sum, card] : best;
    }, [-1] )[1];
}

var creditCardNumbers = ['4916-2600-1804-0530', '4779-252888-3972', 
                         '4252-278893-7978', '4556-4242-9283-2260'];

console.log(cardWithMaxSum(creditCardNumbers));

Upvotes: 2

Redu
Redu

Reputation: 26161

I would like to do this job as follows;

var arr = ['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260'],
    res = arr.map((c,i,a) => [c.match(/\d/g)
                               .reduce((p,c) => +p + +c), c])
             .reduce((p,c) => c[0] >= p[0] ? c
                                           : p, [0])[1];
console.log(res);

Upvotes: 0

jgutierrez
jgutierrez

Reputation: 26

Look, I hope this piece of code will help, be sure to test it.

function getMaxSerialNumb(sNumbers) {
	/*Function that gets the maximun sum of the
	serial number in a list of serials numbers*/
    var n, i, sums;
    i = 0;
    sums = [];
    while (i < sNumbers.length) {
        sums.push(serialSum(sNumbers[i]));
        i++;
    }
    n = sums.lastIndexOf(Math.max.apply(null, sums));
    return sNumbers[n];
}

function serialSum(sNumber) {
	/*Function that gets the sum of a single 
	serial number.*/
    var i, integers, answer;
    integers = sNumber.split(/[-]+/g);
    i = 0;
    answer = 0;
    while (i < integers.length) {
        answer += Number(integers[i]);
        i++;
    }
    return answer;
}
/*Example*/
numbers=['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260']
console.log(getMaxSerialNumb(numbers))

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386550

You could map the number with the value of the sum and seelect then the last largest object and take just the number.

function getMax(array) {
    return array.map(function (a) {
        return { n: a, v: a.match(/\d/g).reduce(function (a, b) { return +a + +b; }) };
    }).reduce(function (r, a, i) {
        return i && r.v > a.v ? r : a;
    }, 0).n;
}

console.log(getMax(['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260']));

Upvotes: 0

Kalman
Kalman

Reputation: 8121

Probably similar to many other wonderful answers here

var creditCardsArr = ['4916-2600-1804-0530', 
                      '4779-252888-3972', 
                      '4252-278893-7978', 
                      '4556-4242-9283-2260'];

// Strip off dashes and convert from string to sum of digits of each card
var creditCardSumOfDigitsArr = creditCardsArr.map(function(cc){
  cc = cc.replace(/-/g, "");
  return cc.split("").reduce(function(a, b){ return a + parseInt(b)}, 0);
});

var indexOfMaxCreditCard =   creditCardSumOfDigitsArr.reduce(function(maxIndexSoFar, cur, curIndex, arr){
  return cur >= arr[maxIndexSoFar] ? curIndex : maxIndexSoFar;
}, 0);

console.log("Credit card with highest sum of digits: " +   creditCardsArr[indexOfMaxCreditCard]);

Upvotes: 0

Daniel
Daniel

Reputation: 8647

Are you looking for index of card number with max sum of digits?

Try this: (ES6)

numbers=['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260']


console.log(
        numbers.map(
                e=>{
                    var value = parseInt(e.replace(new RegExp('-', 'g'),"")),sum = 0;
                    console.log(value);
                    while (value) {
                        sum += value % 10;
                        value = Math.floor(value / 10)
                    }
                    console.log(sum);
                    return sum;
                }
        ).reduce((max, x, i, arr) => x > arr[max] ? i : max, 0)
);

Upvotes: 0

ray
ray

Reputation: 27245

You could use reduce and Math.max to greatly simplify your code. Something like this:

const input = ['4916-2600-1804-0530', '4779-252888-3972', '4252-278893-7978', '4556-4242-9283-2260'];

function sumDigits(str) {
	return Array.from(str).reduce((result, value) => {
		const num = parseInt(value) || 0;
		return result + num;
	}, 0);
}

function findMax(inputArr) {
	return inputArr.reduce(
		(prev, input) => Math.max(prev, sumDigits(input)),
		0
	);
}

console.log(findMax(input));

Upvotes: 0

JstnPwll
JstnPwll

Reputation: 8685

This question sounds a lot like homework. Either way, please don't just copy & paste this code. Read the comments, take some time to understand what it's doing, and perhaps research Array.prototype.sort.

//Some sample data
var numbers = [
  "2345-6789-0123-4567",
  "3456-7890-1234-5678",
  "4567-8901-2345-6789",
  "1234-5678-9012-3456"
];

function getLargestCreditNumber(numbers){
  /*
  Custom sort function to sort the array (smallest to largest).
  Sort function runs in iterations and compares two items from the array
  at a time. We need to return 1 if a > b, -1 if a < b, or 0 if they are
  equal.
  */
  numbers.sort(function(a, b){
    //Split number 'a' by hyphens
    var parts1 = a.split('-');
    //Sum the parts
    var sum1 = parts1.reduce(function(a, b){
       return parseInt(a) + parseInt(b);
    }, 0);
    //Split number 'b' by hyphens
    var parts2 = b.split('-');
    //Sum the parts
    var sum2 = parts2.reduce(function(a, b){
       return parseInt(a) + parseInt(b);
    }, 0);
    //Return number to indicate how these two items compare
    return sum1 > sum2 ? 1 : sum1 < sum2 ? -1 : 0;
  });
  //Return the last item in the array
  return numbers.pop();
}
console.log(getLargestCreditNumber(numbers));

Upvotes: 0

Related Questions