Need help with Credit Card Checker project

Hey, I’ve been working on this project since last night and this morning for quite a few hours. I seem to be stuck at one of the last steps which is asking me to go through the invalid credit card nested array, take the first element, check if it matches a numerical value thats associated with a CC company. The issue im encountering is in the last function im trying to create called idInvalidCardCompanies.

I’m not exactly looking for a straight answer, just trying to be pointed in the correct direction. thank you!

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];
const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];

// All invalid credit card numbers
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];


// Add your functions below:

//function using luhn algorithm to validate card number
let validateCred = (array) =>{

//array to store sum of input card
  let sumUp = [];

//loop that starts from right of array and passes through luhn steps
  for (let i = array.length - 1; i >= 0; i--){
        //conditional that checks array element is even
        if (i % 2 === 0){
          //conditional to see if number is over 9 after *2
          if (array[i]*2 > 9){
            //sends value to sumUp 
            sumUp.push(array[i]*2 - 9);
          }else{
            //sends value to sumUp
            sumUp.push(array[i]*2);
          }  
         }
         else{
           //sends value to sumUp
           sumUp.push(array[i]);
        }
        
    }
    //adds up the inputed array and stores it in sumUp
    sumUp = sumUp.reduce((a, b) => a + b, 0);
    //checks if sum has remainder of 0 to see if valid number;
      if (sumUp % 10 === 0){
        //console.log('Its a valid card number!')
        return true;
      }else{
        //console.log('Invalid credit card number')
        return false;
      }
  } 
//variable that stores the invalid cards
let invalidCards = [];
  //function to create an array of invalid credit cards
let findInvalidCards = (nestedArray) => {

  //rotates from left-right through the nested array
    for (j = 0; j < nestedArray.length; j++){   
      //passes batch through validateCred function to see which cards are invalid   
      if (validateCred(nestedArray[j]) === false) {
        //pushes invalid cards from array to blank array
        invalidCards.push(nestedArray[j]);
      }
    }
    //console.log(invalidCards);
     return (invalidCards);
}

const invalid = findInvalidCards(batch);

let idInvalidCardCompanies = (invalidArr) => {
  let companies = []; 
for(i = 0; i <= invalidArr.length; i++){
  
  switch (invalidArr[i][0]){
    case 3:
      companies.push('Amex (American Express)');
      break;
    case  4:
      companies.push("Visa");
      break;
    case 5:
      companies.push('Mastercard');
      break;
    case 6:
      companies.push("Discover");
      break;
    default:
      console.log("Company not found");
    }
}
}


idInvalidCardCompanies(invalid);

//validateCred(valid3);

So, I ran your code, and received the following error:

TypeError: Cannot read property ‘0’ of undefined

It refers to this line:

If I add a console.log() statement like so:

I see the following output:

3
4
5
3
6
5
3
4
TypeError: Cannot read property ‘0’ of undefined

So, you are getting what you wanted, but the loop continues to run after the last element of the array has been accessed. Why would that be?

hint
for(i = 0; i <= invalidArr.length; i++){
             ^^
//consider the difference between the length of an array and the valid index values of the array

You also have another issue. valid3 appears in your invalid cards array. valid3 is in fact a valid number.

1 Like

Thank you i appreciate the help! I fixed the issue with it continuing to run (i knew it was something small!).

Took me about an hour and a half to figure out how to get the logic to work and stop outputting that valid number into my invalid array. I had a tad bit of help from my brother on that :slight_smile:

then turned my end array, into a unique new set, then back into an array to get rid of the duplicates. It took me quite the time, but i’m glad i’ve gotten over this hurdle and learned some more. alongside dealing with the frustration lol.

/loop that starts from right of array and passes through luhn steps
let count = 1;
  for (let i = arr.length - 1; i >= 0; i--){

        //conditional that checks array element is even
        if (count != 1 && count % 2 === 0){
          //conditional to see if number is over 9 after *2
          if (arr[i]*2 > 9){
            //sends value to sumUp 
            sumUp.push(arr[i]*2 - 9);
          }else{
            //sends value to sumUp
            sumUp.push(arr[i]*2);
          }  
         }
         else{
           //sends value to sumUp
           sumUp.push(arr[i]);
        }
        count++
    }
1 Like

Nice work! :+1: One question. What difference does it make if count is equal to 1 or not? What makes 1 unique?

I don’t think it does matter if its 1 or not. At first when working with my brother 0 had given us a strange error, but maybe that was from something else we tried and fixed. As if i change it to != 0 and count = 0, i get the exact same output.

It doesn’t since 1 % 2 is not equal to 0.

You could set count equal to 0 to start, and then check whether count % 2 is not equal (!=) instead of equal to 2.

oooh, interesting such as. Gives the exact same output.

(count != 0 && count % 2 != 0)

i think getting down the logic and having to make sense of it seems to be the most difficult part for me so far, alongside being able to do so many different things to achieve a solution.

i appreciate you pointing that out.

1 Like

You don’t need the count != 0 part of the condition.

if(count % 2 != 0) //this is all you need; 0 % 2 is equal to zero, so the condition evaluates to falsy without checking: count != 0
C:\Users\todli>node
> 0 != 0 && 0 % 2 != 0
false
> 0 % 2 != 0 //evaluates to false by itself
false
> 0 != 0 //this check is unnecessary
false

okay, i see what you mean now. I didn’t need the first part because it already checks that when i changed it to != 0, geez that slipped my mind.

1 Like

The same logic applies when you originally set count equal to 1:

C:\Users\todli>node
> 1 != 1 && 1 % 2 === 0
false
> 1 % 2 === 0 //evaluates to false by itself
false
> 1 != 1 //this check is unnecessary
false

gotcha, I have another question if you wouldn’t mind answering it. I understand my original code was incorrect as it didn’t work.

if (i % 2 === 0)

But i don’t understand what it was doing, that made it output that valid number as invalid.?

and vice versa.

I don’t understand how adding that count variable is doing what it is, besides that its always going to be odd/even/odd/even in terms of the math correct?

If you consider the difference between invalid3 and the other invalid numbers, you’ll notice it is one digit less. If you use the index of the elements rather than your count variable, you are performing the doubling action on the wrong digits when you have a credit card number that has an odd number of digits.
For example:

const arr1 = [0, 1, 2, 3, 4];
const arr2 = [0, 1, 2, 3, 4, 5];

const addTen = arr => {
  for(let i = arr.length - 1; i >= 0; i--){
    if(i % 2 != 0){
      arr[i] += 10;
    }
  }
}

console.log(arr1);
addTen(arr1);
console.log(arr1);

console.log(arr2);
addTen(arr2);
console.log(arr2); //if we wanted to skip the digit at the end, we goofed...
//we still changed the numbers with odd indices rather than skipping the last digit
//and changing every other digit

Output:

[ 0, 1, 2, 3, 4 ]
[ 0, 11, 2, 13, 4 ]
[ 0, 1, 2, 3, 4, 5 ]
[ 0, 11, 2, 13, 4, 15 ]