Para este desafío de Codewars, no puedo entender por qué la lógica no funciona. He encontrado otras soluciones, pero me gustaría entender por qué esto no funciona:
Los cajeros automáticos permiten códigos PIN de 4 o 6 dígitos y los códigos PIN no pueden contener nada más que exactamente 4 dígitos o exactamente 6 dígitos.
Si a la función se le pasa una cadena de PIN válida, devuelve verdadero, de lo contrario, devuelve falso.
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; } }Hay algunas verificaciones dobles que no necesita hacer, pero las está haciendo porque no está seguro de lo que espera.
Como el tipo de pin .
const splitPin = pin.toString().split('') funciona de cualquier manera para una cadena o un valor numérico, porque está esperando una cadena, la llamada a .toString es necesaria
Pero también que está utilizando Number.isInteger : esta función solo devolverá verdadero si el parámetro es de tipo entero.
Pero dado que pin es una cadena y dividirla devuelve una matriz de cadenas, la llamada Number.isInteger siempre devolverá falso.
Intenta usar isNaN en su lugar. Luego !isNaN(pin[0]) (Gracias a cyberbrain).
Puede optimizar la función desde:
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; } }a algo más limpio:
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 (!isNaN(pin[i])){ finalArr.push(pin[i]); } return } return acceptedLengths.includes(finalArr.length) }o incluso algo como esto:
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) => !isNaN(entry)) // if strength is 4 or 6, return true, else false return acceptedPINLength.includes(numbersArray.length) }Yo diría: no se requiere bucle en absoluto, no tiene que filtrar ningún carácter:
function validatePIN(pin) { const acceptedPINLength = [4, 6]; return acceptedPINLength.includes(pin.length) && !isNaN(pin); }(Gracias a @Amats por la elegante solución con el PINLength aceptado).