JS Loops Credit Card Checker, just need a little push to get me over the hump

https://www.codecademy.com/practice/projects/credit-card-checker

Hello, this is my third run up at this function and I think I’m getting close to cracking it.

I’m not sure how to get the resulting array into the right spot of the code to sum the digits. When I log my newTestArray, I’m just getting a single digit and I’m not completely sure how to get the full array with the .spliced values included.

I think I need to nest another loop somewhere in the first, but my brain is a bit fried and I wouldn’t mind any hints to push me in the right direction.

the console.log at the end is just for testing purposes.

Thanks, see code below

// Add your functions below:

function validateCred(array1) {
  const testArray = array1.slice().reverse();
  const testArray1 = testArray.shift();
  for (let i = 0; i < testArray.length; i +=2) {let testDigit = testArray[i] * 2;
  if (testDigit > 9) {testDigit -= 9};
  let newTestArray = testArray.splice(i, 1, testDigit);
console.log(testArray)
}
};

validateCred(valid1);

You are in Java topic, Java is not JavaScript ;-;

Thanks for the heads up!

Hello, @arc0342986238.

Consider what you really need. Do you need to produce a new array with the updated numbers, or do you only need the sum of the numbers? You can as an intermediate step, create the new array, but it really isn’t necessary.

Looking at your code, you’ve got 3 new arrays created inside your function: testArray, testArray1 and newTestArray. Do you need all of those? If you want to create a new array as a step toward the end goal, you only need one of those. Think about the steps you need to take, and write those down. How would you (a human) determine if a credit card number is valid? Those are the steps to write down. Then you can write code to match those steps.

It appears as though you are wanting to take an array of digits, convert some of those digits to new values producing a new array with the original unchanged digits and the changed digits. You’ve created a new array right off with:

That’s a good first step. You are preserving the original array by making a copy and reversing it. Since you’ve already made a copy, you need only to work with this array. There’s no need to create addition arrays. You’re probably already familiar with how to change an element of an array:

const sampleArray = [1, 1, 1, 1, 1];
sampleArray[2] = sampleArray[2] * 2;
console.log(sampleArray); // [1, 1, 2, 1, 1];

Consider how you can use this to change the elements of the array that need to be changed while preserving those values that need to remain the same.

Also,

Consider whether there is truly a need to remove the ‘check digit’. Could we not just skip it?
For example:

const testArray = [1, 2, 3, 4, 5];
const newTestArray = testArray.slice().reverse();
for (let i = 1; i < newTestArray.length; i += 2) {
  newTestArray[i] = newTestArray[i] * 2;
}
console.log(newTestArray); //[ 5, 8, 3, 4, 1 ]

Excellent tips, thanks so much for the clear explanation.

1 Like

Keep us posted as to your progress. Personally, I have come back to this project probably 5 or 6 times over the last year and a half refactoring my code each time. The first milestone is getting a version that does the job however naive or clunky it may be. My first attempt employed a similar strategy to yours. Then as my knowledge and understanding have increased, light bulbs have gone off, and I have come back to this project, repeatedly, to try something new. My current validateCred function is a single line of code, but it sure didn’t start out that way. Revisiting and refactoring these projects is great experience.

So shortly after digesting your tips, I found the .reduce() method in the documentation and finally got my validateCred() function working! Thank you!


function validateCred(array1) {
  const testArray = array1.slice().reverse();
  const reducer = (accumulator, currentValue) => accumulator + currentValue;
    for (let i = 1; i < testArray.length; i +=2) {testArray[i] = testArray[i] * 2;
  if (testArray[i] > 9) {testArray[i] -= 9};
}
const testDigit = testArray.reduce(reducer);

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

Currently working on the next step to create the findInvalidCards() function:

function findInvalidCards(nestedArray) {
  let invalidCards = [];
for (let i = 0; i > nestedArray.length; i++) {
invalidCards = nestedArray.filter(validateCred(nestedArray[i]));
}
return invalidCards;
};

not entirely sure why the function returns a blank array still. I thought it might be something with my variable scope, but moving things around didn’t seem to change anything. Any advice would be much appreciated!

1 Like

You probably want to return true or false rather than log the values to the console. Since your function doesn’t explicitly return anything, it implicitly returns undefined.

You can return a boolean by simply returning the expression. The expression is evaluated first, and the result is returned:

return someNum % 10 === 0; //returns either true or false
Spoiler:
//you could shorten it to simply:
return testArray.reduce(reducer) % 10 === 0;

P.S. Nice job using .reduce()!

Are you sure you’re not the one who’s got things twisted around?

I think when they said that, the topic was in the Get help>Java category.

Then we need to sort this out. Did somebody move things around?

Yes, me. And for some reason didn’t notify it by writing (know I should have). Don’t remember why exactly, but won’t happen again. Apologies for the confusion @mtf, @codeneutrino, @choco404, @arc0342986238

2 Likes

@midlindner How can your validateCred function be of just single line,mine is of like 40-45 lines,yeah I am light years behind you but how is it possible to reduce the lines of code to THIS much extent?

1 Like

Good catch, I fooled myself into thinking I had solved it. After a little more hammering I think I sussed out what I was mis-coding with the .filter() method. Iterators are still very fresh, but my new code for the findInvalidCards() function has returned a set of arrays.

function findInvalidCards(nestedArray) {

let invalidCards = nestedArray.filter(array => !validateCred(array));

return invalidCards;}

console.log(findInvalidCards(batch));

I still need to thread through my work a few more times to properly comprehend just what I did, but it’s a step closer to wrapping my head around how iterators handle their elements. Couldn’t have done it without your help!

1 Like

Hello, @faisalrehman19, and welcome to the forums.

As I stated, it didn’t start out that way at all, and the one liner may not be the most efficient method. I did it, to see if I could. As you learn more about the built in array methods and iterators, you’ll see how you can chain methods together rather than writing a new line of code for each step. Don’t get hung up on trying to condense everything or spending too much time trying to understand my code, but here it is if you’d like to satisfy your curiosity.

const validateCred = credNum => (credNum.slice().reverse().reduce((t, d, i) => i % 2 === 0 ? t + d : d > 4 ? t + (d * 2 - 9) : t + d * 2)) % 10 === 0; 

Project completed, thanks for the push. This one took me hours and hours but feels like a huge accomplishment to have completed, I wouldn’t say it was “fun” but I definitely learned a ton! Looking forward to coming back and reworking it.


function validateCred(array1) {
  const testArray = array1.slice().reverse();
  const reducer = (accumulator, currentValue) => accumulator + currentValue;
    for (let i = 1; i < testArray.length; i +=2) {testArray[i] = testArray[i] * 2;
  if (testArray[i] > 9) {testArray[i] -= 9};
}
const testDigit = testArray.reduce(reducer);

if (testDigit%10 === 0) {return true;
} else {
  return false;
}
};

function findInvalidCards(nestedArray) {
let invalidCards = nestedArray.filter(array => !validateCred(array));
return invalidCards;}


 function idInvalidCardCompanies(nestedArray) {let invalidCardCompanies = nestedArray.map(array => {switch (array[0]) {
  case 3:
  return 'Amex';
  break;
  case 4:
  return 'Visa';
  break;
  case 5:
  return 'Mastercard';
  break;
  case 6:
  return 'Discover';
  break;
  default:
  return 'Company not found';
  break;}})
  let invalidList = invalidCardCompanies.filter((c, index) => {return invalidCardCompanies.indexOf(c) === index;
  })
  return invalidList;
}