首页 > 解决方案 > Javascript unshift(),递归和制作数组

问题描述

function countdown(n) {
  if (n < 1) {
    return [];
  } else {
    const arr = countdown(n - 1);
    arr.unshift(n);
    return arr;
  }
}

我在 freeCodeCamp 中找到了上面的代码。我在 VS 代码上运行它。它有效,但我不明白如何。这是我的问题:您如何unshift()处理尚未声明为数组的变量,例如[]?它只是这么说const arr = countdown(n-1)。它并没有说那const arr是一个数组,例如“ []”。如果我尝试将unshift()整数转换为已声明为“ arr”而没有任何“ []”的变量,它将作为错误运行。但是,在我在 freeCodeCamp 上找到的这段代码中,它可以工作。为什么?

标签: javascriptarraysrecursion

解决方案


替代

如果我说x = 5然后问“什么是x + 3?” . 无需太多帮助就可以回答,8。当你被问到你是如何得出答案的时,你解释说你用它的值代替 x了五,然后加了三。

如果给定一个函数f(x) = 3 * x + 2or max(a,b) = a > b ? a : b,我可以问你其他问题,比如什么是f(4)or max(9,7)?你会以同样的方式得到答案:

  • 是什么f(4)
    • 是什么f?→fx -> 3 * x + 2
    • 是什么x?→ x4
    • 是什么3 * 4 + 2
      • 是什么3 * 4?→ 答案是12
      • 是什么12 + 2?→ 答案是14
      • 答案是14
    • 答案是14
  • 答案是14

  • 是什么max(9,7)
    • 是什么max?→max(a,b) => a > b ? a : b
    • a和是什么b?→a9b7
    • 是什么9 > 7 ? 9 : 7
      • 是什么9 > 7?→ 答案是true
      • 是什么true ? 9 : 7?→ 答案是9
      • 答案是9
    • 答案是9
  • 答案是9

因此,使用递归函数,我们可以使用替换来回答这些问题

  • 是什么countdown(5)
    • 是什么countdown
      • countdown
        function countdown(n) {
          if (n < 1) {
            return [];
          } else {
            const arr = countdown(n - 1);
            arr.unshift(n);
            return arr;
          }
        }
        
    • 是什么n?→n5
    • 什么是 ...?
      if (5 < 1) {
        return [];
      } else {
        const arr = countdown(5 - 1);
        arr.unshift(5);
        return arr;
      }
      
      • 是什么5 < 1。→ 答案是false
      • 什么是 ...?
        if (false) {
          return [];
        } else {
          const arr = countdown(5 - 1);
          arr.unshift(5);
          return arr;
        }
        
        • 答案是
          const arr = countdown(5 - 1);
          arr.unshift(5);
          return arr;
          
        • 是什么arr
          • 答案是countdown(5 - 1)
          • 是什么5 - 1?→ 答案是4
          • 是什么countdown(4)

那是arr什么?

使用替换来计算countdown(5)导致我们计算countdown(4),我们可以再次使用替换。countdown(4)看起来和以前几乎一模一样,当你继续往下看时countdown(3)countdown(2)我们会注意到这种n - 1模式正在发挥作用。直到最后n = 0,条件n < 1是现在true......

  • 是什么countdown(0)
    • 答案是[]

我们可以一直使用替换 -

  • 是什么countdown(3)
    • 是什么arr
    • arrcountdown(3 - 1)
    • 是什么countdown(2)
      • 是什么arr
      • arrcountdown(2 - 1)
      • 是什么countdown(1)
        • 是什么arr
        • arrcountdown(1 - 1)
        • 是什么countdown(0)
          • 答案是[]
        • arr[]
        • 是什么arr.unshift(1)?→ * 答案是[1]
        • 答案是[1]
      • arr[1]
      • 是什么arr.unshift(2)?→ 答案是[2,1]
      • 答案是[2,1]
    • arr[2,1]
    • 是什么arr.unshift(3)?→ 答案是[3,2,1]
    • 答案是[3,2,1]
  • 答案是[3,2,1]

一个警告

递归是一种功能性遗产,因此将其与功能性原则一起使用会产生最佳结果。这意味着避免诸如突变、变量重新分配和其他副作用之类的事情。上面我们可以使用替换,因为countdown具有引用透明性。这是一种奇特的说法,如果给出相同的输入,该函数总是返回相同的结果。在函数学科中,您总是以这种方式设计函数,因此您的程序可以组装和组合,就像不断发展的方程组中的公式一样。

没有arr

JavaScript 对函数式风格有很强的支持,所以我们的程序可以用丰富的表达式来编写。程序语义不受中间赋值arr和语法样板(如if, else, return, 和{...}lie about)的干扰。

const countdown = n =>
  n < 1
    ? []
    : [ n, ...countdown(n - 1) ]
    
console.log(countdown(5))

[5,4,3,2,1]

推荐阅读