Existe esta función:
function countup(n) { if (n < 1) { return []; } else { const countArray = countup(n - 1); countArray.push(n); return countArray; } } console.log(countup(5));¿Cómo se empuja [] primero? Por el código, parece que se está contando desde n. ¿Alguien puede explicar?
Pregunta adicional: ¿Por qué escribir así cuando puedo escribir:
function countup(n){ let answer = [] for (let i = 1; i <= n; i++){ (i<n) ? answer.push(i) : answer.push(n) } return answer } console.log(countup(5));que es una función más corta. ¡gracias de antemano!
Aunque los números están en orden descendente a partir de n , en realidad se colocan primero en el número más pequeño. Esto se debe a que antes de que ocurra la operación push() , seguimos bajando en la pila de recursividad cuando llamamos a countup(n - 1) cada capa de la recursividad. Por eso llegamos a un punto en el que n < 1 , es decir, 0 , donde se devuelve una matriz vacía.
A continuación, nos encontramos con la primera operación array.push() y, por lo tanto, el primer número que se inserta en la matriz es en realidad 1 y no n . Luego, las capas de recurrencia comienzan a enrollarse y empujamos los números 2, 3, y así sucesivamente hasta n .
Sí, puedes lograr lo mismo usando un bucle for tradicional, pero supongo que solo quieren explicar cómo funciona la recursividad.
Para comprender las recursiones, a veces es necesario seguir la ejecución del código manualmente. Ahora, la siguiente línea provoca la llamada recursiva y resta uno del número y luego lo pasa a la llamada recursiva.
const countArray = countup(n - 1); Ahora imagina, si pasaste 5 a la llamada de función inicial así:
countup(5); Como 5 no es menor que 1, se ejecutará el bloque else . La primera línea en el bloque else es la llamada recursiva. Entonces, cuando su programa encuentra la llamada recursiva, detiene la ejecución de la función actual hasta que finaliza/devuelve esa llamada de función recursiva. Entonces la primera llamada recursiva será:
const countArray = countup(4); en consecuencia, el mismo proceso se repetirá hasta que n sea igual a 0. Como 0 es menor que 1, la condición if se evaluará como true . y devolverá una empty array .
Después de la llamada recursiva, empuja el número a la matriz devuelta por la llamada recursiva. entonces la matriz en ese punto contendrá [0] y luego [0, 1] y seguirá agregando números hasta que se hayan calculado todas las llamadas recursivas y luego ejecutará el resto de la llamada de función inicial.
Muchas veces, la recursividad puede ser reemplazada por bucles, pero ese no es siempre el caso. Como programador, uno debe ser consciente de este importante tema.
Dado que countup() está completamente dividido por una instrucción if que depende de n , primero veamos qué se ejecuta para diferentes valores de n .
Para que sea mucho más fácil de seguir, añadiremos nuestra n actual al nombre de la variable de countArray :
n == 5: const countArray5 = countup(4); countArray5.push(5); return countArray5; ⋮ n == 1: const countArray1 = countup(0); countArray1.push(1); return countArray1; n == 0: return []; Ahora ampliemos secuencialmente cada llamada interna a countup(n) :
countup(5) { const countArray5 = countup(4); countArray5.push(5); return countArray5; } countup(5) { const countArray5 = countup(4) { const countArray4 = countup(3); countArray4.push(4); return countArray4; }; countArray5.push(5); return countArray5; } Expansión hasta countup(0) :
countup(5) { const countArray5 = countup(4) { const countArray4 = countup(3) { const countArray3 = countup(2) { const countArray2 = countup(1) { const countArray1 = countup(0) // countup(0) returns [] so countArray1 = []; countArray1.push(1); // Then push '1' to countArray1; return countArray1; // Return [1] at counterArray2 = countup(1) above }; countArray2.push(2); // countArray2 was [1], now push '2' to make it [1,2] return countArray2; // Return [1,2] at countArray3 = countup(2) above }; countArray3.push(3); // Push '3' to countArray3 => [1,2,3] return countArray3; // return [1,2,3] at countArray4 = countup(3) }; countArray4.push(4); // Push '4' to countArray4 => [1,2,3,4] return countArray4; // Return [1,2,3,4] at countArray5 = countup(4) }; countArray5.push(5); // Push '5' to countArray5 => [1,2,3,4,5] return countArray5; // countup(5) returns [1,2,3,4,5] }