Credit Card Checker Challenge Project (JavaScript)

I am almost finished with the challenge, but I just learned that my function is not working properly when it comes to AMEX cards. I’ve been staring at my code for some time now… But that’s the only problem I am having at the moment. Here’s the code I am referring to:

const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const validateCred = (arr) => {
  let sum = 0;
  for (let i = arr.length - 1; i >= 0; i--){
    let digit = arr[i];
    
    if(i % 2 == 0 ){
      digit *= 2;   
      }
    if(digit > 9){ 
      digit -= 9;
      }
    //console.log(digit);
    sum += digit;
  }
  return sum % 10 === 0 ? 'Valid number.' : 'Invalid number.. '
} 

console.log(validateCred(valid3)); 

I will clean my code up later. I am trying to understand the concepts now. But I can’t tell what I am missing at the moment.

This little piece of code here is what I was missing " (arr.length - i) % 2 == 0 "… What is the significance of this piece of code? Why did I need that versus " i % 2 == 0 "? Does (arr.length - i) remove the rightest number?

Hi! I’ve got most of a solution, but there’s one issue that I can’t resolve. In the first function, which checks whether cc numbers are valid or not, my code keeps changing the input array, but I intend it to create a copy of the input array that I change. In other words, I want to double the digits of the copy, but it seems to be doing the original. This doesn’t cause a problem for this function, but it causes problems down the road when I try to identify the companies, since I don’t have the originals anymore. Here’s the code, along with some comments and tests that highlight the problem:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]; //this is so I can test the function and demonstrate the problem I'm having

function validateCred(ccNumber) {

  let doubledArray = ccNumber; //this is where I create the copy of the cc number to work with

  for (let i=ccNumber.length-2; i>= 0; i = i-2){

    doubledArray[i] = 2*doubledArray[i];

    //this is changing ccNumber, as is shown by these tests, which output identical arrays, even though I intend the ccNumber to not change:

   console.log(doubledArray);

    console.log(ccNumber)

    if (doubledArray[i]>9) {

      doubledArray[i]=doubledArray[i]-9

    }

  }

 const reducer = (previousValue, currentValue) => previousValue + currentValue;

let sum = doubledArray.reduce(reducer);

  if (sum % 10==0) {

    return true

  } else {

    return false

  }

}

validateCred(valid1)  //this is to test the function and demonstrate the problem, which is that ccNumber changes

I see a problem here:

let doubledArray = ccNumber; //this is where I create the copy of the cc number to work with

The = doesn’t actually copy the array, it just makes a new reference to it, since an array is a kind of object.
thus doubledArray and ccNumber are the same array.
and changing what’s in doubledArray changes what’s in ccNumber.

One workaround is to use Array.from() to make a new array.
like this:

let doubledArray = Array.from(ccNumber);

Look up some of the other JavaScript array methods too, they may be useful to you.

I liked your approach;
using a variable or counter to keep track of the position in the array relative to the end of the array (to know how far you are from the end of the array in each iteration) was a good idea.

Oh, thanks so much! I think I learned that once, but obviously forgot and/or never really understood it. Anyways, this helped and it’s working well now.

Thanks again!

It feels like the way I arrived at the answer is a bit randomly strange, looking over other peoples work it seems I have to many steps, would appreciate some feedback.

Thanks all.

I dont think there is a right or wrong if your code is working like the lesson says you always have time to refactor and shorten your code check out mines I think im like 15 lines short of you

// Add your functions below:

const validateCred = (arr) => {

// created a new arr variable with the value of the enter arr reversed.

let newArr = arr.reverse();

// New variable that will hold the sum of the entered arr

let sum = 0;

for (let i = 0; i < newArr.length; i++) {

 if (i % 2 == 1) {

// multiply every other value by 2

arr[i] *= 2;

// nested if statement to test another condition

   if (arr[i] > 9) {

// if doubled arr value exceeds 9 take away 9

  arr[i] -= 9;

 }

}

// adding up all the arr values

sum += arr[i]; //end of for loop

}

// console.log(sum);

if (sum % 10 == 0) {

return true;

} else {

return false;

}

}

const findInvalidCards = (arrNest) => {

// The variable used to return the nest array list of invalid cards

const newArrNest = ;

arrNest.forEach(function (array) {

// console.log(validateCred(array)); //Test Statement

// conditional statement to add the invalid cards to the newArrNest

if (validateCred(array) == false) {

  newArrNest.push(array);

  // console.log(newArrNest); //test Statement

}

})

return newArrNest;

}

function idInvalidCardCompanies(invalidArrNest) {

const companyArr = ;

// console.log(invalidArrNest);

invalidArrNest.forEach(function (array) {

if (array[0] == 3 && companyArr.indexOf('Amex (American Express)') == -1) {

  

  companyArr.push('Amex (American Express)');

} else if (array[0] == 4 && companyArr.indexOf('Visa') == -1) {

  

  companyArr.push('Visa');

} else if (array[0] == 5 && companyArr.indexOf('Mastercard') == -1) {

  companyArr.push('Mastercard');

} else if (array[0] == 6 && companyArr.indexOf('Discover') == -1) {

  companyArr.push('Discover');

} else {

  console.log('This card Company was not found');

}

})

return companyArr;

}

// console.log(idInvalidCardCompanies(findInvalidCards(batch)));

// console.log(findInvalidCards(batch));

// console.log(validateCred(invalid1));

// console.log(validateCred(valid1));

True indeed. I hope to re factor to a more concise format.

When i looked over your code the only thing i really can find is that the array was not reversed what method did you choose to go with when completing the project here take a look at my code nothing is wrong with using
i % 2 == 0

// Add your functions below:
const validateCred = (arr) => {
// created a new arr variable with the value of the enter arr reversed.
let newArr = arr.reverse();
// New variable that will hold the sum of the entered arr
let sum = 0;
for (let i = 0; i < newArr.length; i++) {
if (i % 2 == 1) {
// multiply every other value by 2
arr[i] *= 2;
// nested if statement to test another condition
if (arr[i] > 9) {
// if doubled arr value exceeds 9 take away 9
arr[i] -= 9;
}
}
// adding up all the arr values
sum += arr[i]; //end of for loop
}

// console.log(sum);
if (sum % 10 == 0) {
return true;
} else {
return false;
}
}

1 Like

Hi!
This is my solution.
Maybe someone can check? ))

Really enjoyed this project, specifically converting invalid numbers into valid numbers.
Would like some feedback. :slightly_smiling_face:

Hello All,

Sharing as instructed Codecademy export · GitHub

The only extra effort left to me would be a proper factory function for the company object array. Sorry for the lack of comment code.

Hello all,

I’ve got to the end of task 5 and have tried using switch and else if statements which give 2 different company arrays. I’m not sure which is correct.

Should the ‘company not found’ be included as there are card number arrays which don’t start with correlating numbers. The else if statement i wrote includes ‘company not found’ due to reason above.

Unsure which is correct!

    default: 'company not found'

sorry i’m not sure what you mean?

I have the default at the end of the switch statement but it doesn’t get returned in the array, just amex and discover.

When I used else if statements amex, discover and company not found are returned in the array.

I’m not sure if it should be returned or not is where i’m at a loss. I think it should be and can see why its not being returned if so. For the default I haven’t push() ed it into the array…

What does your switch look like?

const idInvalidCardCompanies = cardNums => {

let companies =

for (let i = 0; i < cardNums.length; i ++) {

switch (cardNums[i][0]) {

  case 3:

  if (companies.indexOf('Amex') === -1) {

      companies.push('Amex');

    };

    break;

    case 4:

  if (companies.indexOf('Visa') === -1) {

      companies.push('Visa');

    };

    break;

    case 5:

  if (companies.indexOf('Mastercard') === -1) {

      companies.push('Mastercard');

    };

    break;

    case 6:

    if (companies.indexOf('Discover') === -1) {

      companies.push('Discover');

    };

    break;

    default:  'Company not found'


};

};

return companies

};

not sure how to post it so it looks nice and neat. hopefully it pastes alright.

Shouldn’t you be checking the first digit? That is what the switch is set up for. Remove the if statement and just push the company name.