For this Codewars challenge, I cannot understand why the logic is not working. I've found other solutions, but would like to understand why this is not working:
ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.
If the function is passed a valid PIN string, return true, else return false.
function validatePIN (pin) {
const splitPin = pin.toString().split('')
const finalArr = [];
for (let i = 0; i < splitPin.length; i ){
if (!Number.isInteger(pin[i])){
return false;
} else if (Number.isInteger(pin[i])){
finalArr.push(pin[i]);
}
}
if(finalArr.length === 4 || finalArr.length === 6){
console.log(finalArr.length)
return true;
}
}
CodePudding user response:
There are some double checks that you don't need to do but you are doing because you're not sure what you're expecting.
Like the type for pin
.
const splitPin = pin.toString().split('')
works either way for a string or number value, because you are expecting a string, the call to .toString
is unneccesary
But also that you're using Number.isInteger
- this function will only return true if the function is of type integer.
But since pin
is a string and splitting it returns an array of strings, the Number.isInteger
call will always return false.
Try using parseInt
instead. Then check for parseInt(pin[0]) !== NaN
.
You can streamline the function from:
function validatePIN (pin) {
const splitPin = pin.toString().split('')
const finalArr = [];
for (let i = 0; i < splitPin.length; i ){
if (!Number.isInteger(pin[i])){
return false;
} else if (Number.isInteger(pin[i])){
finalArr.push(pin[i]);
}
}
if(finalArr.length === 4 || finalArr.length === 6){
console.log(finalArr.length)
return true;
}
}
to something cleaner:
function validatePIN (pin) {
const acceptedLengths = [4, 6]
const splitPin = pin.toString().split('')
const finalArr = [];
for (let i = 0; i < splitPin.length; i ){
// You don't need to do an else, since you're only
// checking for one condition.
// just return directly
if (parseInt(pin[i]) !== NaN){
finalArr.push(pin[i]);
}
return
}
return acceptedLengths.includes(finalArr.length)
}
or even something like this:
function validatePIN(pin) {
// Set a variable for the accepted length
const acceptedPINLength = [4, 6];
// If we have to check if a value in pin is an integer or not
// then the pin variable is a string and can't be a number.
// So skip the .toString and just split it directly.
const numbersArray = pin.split('')
.filter((entry) => parseInt(entry) !== NaN)
.join('');
// if strength is 4 or 6, return true, else false
return acceptedPINLength.includes(numbersArray.length)
}
CodePudding user response:
I would say: no loop required at all, you don't have to filter any characters:
function validatePIN2(pin) {
const acceptedPINLength = [4, 6];
return acceptedPINLength.includes(pin.length()) && !isNaN(pin);
}
(Thanks to @Amats for the elegant solution with the acceptedPINLength.)