Credit Card Checker Challenge Project (JavaScript)

return invalid.forEach(card => console.log(card.join('') + ' is invalid.'));

There’s your answer. Array.forEach() has no return so JS returns the default, undefined.

thank you. but i don’t know how to fix that to not get the ‘undefined’ but still keep the idea of what i’m doing.

1 Like

Remove the return, and let the forEach run the procedural code in its body. There is nothing to return.

Here’s my solution for the project. Can probably optimize in a few places. Let me know what you think, and thank you in advance!

Thank you anyways.
I have removed the return but still got the same results printing ‘undefined’.

1 Like

Default returns. They actually disappear if we continue on. I wouldn’t sweat this one if you are getting what you otherwise expect. Keep forging ahead.

1 Like

Hello, this is my credit card checker solution, please any advice, best regards

Here is my solution to this project. Feel free to comment and compare it to your own.
https://github.com/mikejm15/Sample-Projects/blob/5874c43243118a4f1f51acb197126f2d8d8086c1/credit-card-checker/main.js

Hi folks,
I am having issues running the code below.
When I run the following:

function validateCred(array) { let checkArray = array.slice(); const checkDigit = checkArray.pop(); checkArray.reverse(); const sumArray = []; for (let i = 0; i = checkArray.length; i++) { let digit = checkArray[i]; if (i % 2 === 0) { digit *= 2; if (digit > 9) { digit -= 9; sumArray.push(digit); }else { sumArray.push(digit); } }else { sumArray.push(digit); } } const sumOfArray = sumArray.reduce((a, b) => a + b); if (sumOfArray % 10 === checkDigit) { return true; }else { return false; } }

I get the following error

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/usr/bin/node]
2: 0x134e91c [/usr/bin/node]
3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
5: v8::internal::factory::NewUninitializedFixedArray(int) [/usr/bin/node]
6: 0xe1e28d [/usr/bin/node]
7: 0xac61e0 [/usr/bin/node]
8: v8::internal::Runtime_ArrayPush(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
9: 0x264ffd20ea5f
/home/ccuser/.bin/node: line 3: 28 Aborted /usr/bin/node --max-old-space-size=200 $@

I have done some googling and it seems like there is a memory leak but I am struggling to debug when the code won’t even run.

Is anyone able to offer a suggestion?

    for (let i = 0; i = checkArray.length; i++) {
        let digit = checkArray[i];
        if (i % 2 === 0) {
            digit *= 2;
            if (digit > 9) {
                digit -= 9;
                sumArray.push(digit);
            }else {
                sumArray.push(digit);
            }
        }else {
            sumArray.push(digit);
        }
    }

Finding problems begins with finding code bloat and reducing it.

sumArray.push(digit)

This in not a conditional action so can be left to the end of the loop.

for (..) {
    if (...) {
    
    }
    sumArray.push(digit)
}

Looking at the code, the popped checkDigit doesn’t look to be inserted in the sumArray. Not that it matters, but we can reconstruct the initial array in the exact order using unshift() instead of push().

    const checkDigit = checkArray.pop();    
    checkArray.reverse();                   
    const sumArray = [checkDigit];  

    ...

    sumArray.unshift(digit)

As I understand this particular adaptation of the Luhn algo does not compare with the check digit, but takes the sum of ALL the digits and divides by 10. That’s why the checkDigit is inserted.

Run your code after these changes and report back, please.

1 Like

Hi mtf,

Thank you for your response.
You are right that my code was bloated, I was writing code in an inefficient manner.

I have refactored the code as follows.

function validateCred(array) { let checkArray = array.slice(); checkArray.reverse(); let total = 0; for (let i = 0; i <= checkArray.length - 1; i++) { let digit = checkArray[i]; if (i % 2 === 1) { digit *= 2; if (digit > 9) { digit -= 9; total += digit; }else { total += digit; } }else { total += digit; } } return(total % 10 === 0); }

My for loop was originally set to “i = checkArray.length” which was throwing an infinite loop and causing the fatal error.

Thanks again.

1 Like

Hello everyone, here is my version of the creditCardChecker, appreciate your review and feedback. Thank You

Hello, everyone!
Complete beginner here. The code seems to work, but if I call the function with the same valid array , it returns false. Does it matter? I suspect it has something to do with the methods (slice, reverse), but still I couldn’t figure out what is happening. If someone knows, please reply. Thanks.

Code:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];

function validateCred(cardNum){
cardNum.slice(-1);
cardNum.reverse();
 let sum = 0;
 for(let i = 0; i < cardNum.length; i++){
 if((cardNum.length[i])%2 != 0){
    let double = cardNum[i] * 2;
    if(double > 9){
      double -= 9;
    }else{
      sum += cardNum[i];
      if (sum%10 == 0){
      return true;
      }else{
        return false;
        }
      }
    }
  }
}
console.log(validateCred(valid1));
console.log(validateCred(invalid1));
console.log(validateCred(invalid1));
console.log(validateCred(valid1));

Output:
true
false
false
false (should be true, I guess)

That needs assignment. However, if your objective is to remove the last element, you could pop it and assign it. Remember that it is intended as part of the sum.

cardNum.reverse();
sum = cardNum.shift();

Don’t test the sum inside the loop. Complete the iteration and accumulation and then test after the loop.

So we’ve now got the original array reversed, with what is now the first value removed and added to the accumulator and we can begin the doubling from the first element, and every other on after that. For that we don’t need to know the length, just for setting up the loop.

for(let i = 0; i < cardNum.length; i++) {
   if (i % 2 === 0) {
      const double = cardNum[i] * 2;
      if (double > 9) {
        double -= 9
      }
      sum += double
  } else {
    sum += cardNum[i]
}
return sum % 10 === 0;

Thank you very much. I will study your answer.

1 Like

You’re welcome. I edited the if statement.

1 Like

I am a complete beginner and wanted to share my solution. Any feedback would be appreciated. Thanks!

I took a look at the code and it looks great! I actually learned a few things from it as well. I’m so used to using regular loops I actually had to look up those JS array functions which I’m honestly not that familiar with and it was helpful.

The only thing I did different (from a logic perspective) is not adding “Company not found” in the array of credit card companies. From what I understood of the instructions, they wanted the error logged. So I just logged it and didn’t push anything to the array, if it didn’t match any of the card companies.

All in all, awesome job and keep it up!