Credit Card Checker Challenge Project (JavaScript)

Can anyone explain how the switch statement is working in the codecademy solution?
Specifically: how is the switch statement accessing .indexOf before anything has been pushed in to the companies variable.

The call to .indexOf() is in a loop. So if the first time a company match is checked, .indexOf() will return -1, meaning that array doesn’t contain that item. The item is then pushed into the companies array. On the next iteration, if the same company is found again, then the index value will be zero or higher and the company will not be added again.

[CreditCardChecker.js · GitHub]

Hi,

Here is my code for the challenge. I’d really appreciate any feedback, especially any useful ways to make it a bit shorter.

Thanks :slight_smile:

In my opinion, shorter is not always better. It shorthand and tricky code is fun for short challenges, but can make it very difficult for someone else to dissect your code.

You have a logic error in your code, when checking for invalid companies, your code will return an invalid code for every company except discover:

 if (digitOne.some((digit) => digit != (3 && 4 && 5 && 6))) {
    providers.push("Company not found");
  }
console.log(idInvalidCardCompanies(findInvalidCards([invalid1, invalid1])));
console.log(idInvalidCardCompanies(findInvalidCards([invalid4, invalid4])));

console.log(3 !== (3 && 4 && 5 && 6));

Console results:

(2) ['Visa', 'Company not found']
(1) ['Discover']
true

Hi @1moregame,

Thank you for looking through my code and testing it, I’ve adjusted it now and it should hopefully work!

if (digitOne.some(digit => ((digit != 3) && (digit != 4) && (digit != 5) && (digit != 6)))) {
    providers.push('Company not found');
  }; 

Been preserving through JavaScript. Quite enjoyed this project - found it to be good practice for the concepts that were introduced.

// 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: const validateCred = arr => { let testCard = Array.from(arr); const checkSumDigit = testCard[testCard.length - 1]; let doubleFlag = false; for (let idx = testCard.length - 2; idx >= 0; idx--) { doubleFlag = !doubleFlag; if (doubleFlag) { testCard[idx] *= 2; if (testCard[idx] > 9) { testCard[idx] -= 9; } } } const sum = testCard.reduce((accumulator, currentVal) => accumulator + currentVal); return ((sum % 10) === 0) }; const findInvalidCards = arr => { let invalidCards = []; for (const card of arr) { if (!validateCred(card)) { invalidCards.push(card); } } return invalidCards; }; const idInvalidCardCompanies = arr => { let issuerID = 0; let invalidIssuers = [] let cardIssuerIdx = 0; for (const card of arr) { issuerID = card[0]; switch (issuerID) { case 3: cardIssuerIdx = invalidIssuers.indexOf('Amex'); if (cardIssuerIdx === -1) { invalidIssuers.push('Amex'); } break; case 4: cardIssuerIdx = invalidIssuers.indexOf('Visa'); if (cardIssuerIdx === -1) { invalidIssuers.push('Visa'); } break; case 5: cardIssuerIdx = invalidIssuers.indexOf('Mastercard'); if (cardIssuerIdx === -1) { invalidIssuers.push('Mastercard'); } break; case 6: cardIssuerIdx = invalidIssuers.indexOf('Discover'); if (cardIssuerIdx === -1) { invalidIssuers.push('Discover'); } break; default: console.count('Company not found'); } } return invalidIssuers; }; console.log(idInvalidCardCompanies([invalid1])); // Should print['visa'] console.log(idInvalidCardCompanies([invalid2])); // Should print ['mastercard'] console.log(idInvalidCardCompanies(findInvalidCards(batch))); // Find out which companies have mailed out invalid card

Hey All,

here is my solution to the credit card checker, any feedback welcome.

Thanks

Here’s my solution
https://www.codecademy.com/workspaces/62d3a18e16feec5ef763431e

Hi,
I just looked at your code, and I was curious to know what is this line doing exactly?

for (array of nestedArray) {
validateCred(array) || invalidCards.push(array)
}

here is my code for the credit card checker :slight_smile: let me now if you have any improvement suggestion;

https://www.codecademy.com/workspaces/62da38dc551a7175e9da3ab3

My solution to the last task

const idInvalidCardCompanies = function(arr) {
  const digits = {
    3: 'Amex (American Express)',
    4: 'Visa',
    5: 'Mastercard',
    6: 'Discover' 
  }

  const companies = []

  arr.forEach(card => {
    let first = card[0]
    if (first in digits && !(companies.includes(digits[first]))) {
      companies.push(digits[first])
    }
    else {
      console.log('Company not found')
    }
  })
  return companies

}

My solution:

const validateCred = (arr) => {
    const computedDigits = [...arr].reverse().map((digit, ind) => {
        return ind % 2 === 0 ? digit : (digit * 2 > 9 ? digit * 2 - 9 : digit * 2);
    })
    const sum = computedDigits.reduce((previousValue, currentValue) => previousValue + currentValue);
    return sum % 10 === 0;
}

// Test functions:
console.log(validateCred(valid1));      // Should print true
console.log(validateCred(invalid1));    // Should print false

const findInvalidCards = (arr) => {
    return [...arr].filter((card) => {
        if(!validateCred(card)) return card;
    });
}

console.log(findInvalidCards(batch))

const idInvalidCardCompanies = (arr) => {
    const companyList = [...arr].map(card => {
        if (card[0] === 3) return 'American Express';
        if (card[0] === 4) return 'Visa';
        if (card[0] === 5) return 'Mastercard';
        if (card[0] === 6) return 'Discover';
        return 'Company not found';
    })
    return [...new Set(companyList)];
}

// Test function
console.log(findInvalidCards([valid1, valid2, valid3, valid4, valid5]));            // Shouldn't print anything
console.log(findInvalidCards([invalid1, invalid2, invalid3, invalid4, invalid5]));  // Should print all invalid cards

console.log(idInvalidCardCompanies(batch));

Github Repo Link

it’s called short-circuit evaluation. in this case with the OR operator, if validateCred returns false, then run invalidCards.push.

so for ||, the second expression only executes when the first returns false. there’s also && where the second only runs when the first return true.

this is good in this case cuz you don’t wanna write a ternary like this "validateCred(array) ? do nothing : invalidCards.push(array) or writing in if else would be too long and unneccessary

1 Like

check ? (check = false) : (check = true); can be written more elegantly like this check = !check. this way check will be flipped in each iteration.

return sum % 10 === 0 ? true : false; you just need to write return sum% 10 === 0` the return value will be automatically evaluated for you to either true or false.

also if i remember correctly, the requirement is that if you can’t match a company to the invalid card, you just need to console.log(‘unknown company’) instead of adding "unknown"to the array.

Thank you so much for the explanation, this is going to be super useful in the future.

1 Like

Thanks for your review and the tips. I like how it make the code look cleaner.

I’m starting to understand better how to use boolean value a bit more now. I really appreciated your explanation.

I’m 25% done in the course, if you happen to be looking for pair programing to work on some project let me know, i would love to start working in a team :slight_smile:

My solution, I feel like some logic couldve been more efficient.

Here is my final solution :slightly_smiling_face:

hey i’m also at 25%. sure we could do some pair programming work together. I’ve never done that but i should start it now. I’m getting to part 12. Portfolio Project: JavaScript Syntax now. Let’s connect

Awesome, I haven’t done that neither but I’m excited to try it out.
How could we do that? maybe we could start by setting a meeting and talk about our experience and how we could work on a project together? what do you think.
We could connect on zoom or what’s app (or anything else if you have a better idea). I’m in Sri Lanka at the moment so i’m in the Indian Time zone, what about you?