【问题标题】:Best way to approach recursion in JavaScript?在 JavaScript 中处理递归的最佳方法?
【发布时间】:2017-08-11 00:44:06
【问题描述】:

我主要使用 Python 进行编程。今年,我学会了如何使用它进行递归。

我的教授教给我的一个非常好的技巧是像这样使用列表推导:

def list_all(obj):  

    if not isinstance(obj, list):  
        return [obj]  
    else:  
        return sum([list_all(x) for x in obj], []) 

现在我越来越多地使用 JS 而不是 Python,我想知道你可以在语言中使用哪些特定的内置函数来帮助递归。我知道列表理解在 JavaScript 中已被弃用,所以显然我不能再使用它们了。 map 或 filter 在处理递归时会很好地替代列表推导吗?如果不是,那又如何?

【问题讨论】:

  • “我知道列表推导在 JavaScript 中已被弃用” - 谁告诉你的?!我们什么时候有列表推导式,为什么它们会被弃用!?
  • @AndrewLi: [for (x of [1,2,3]) x*x] - 在你的 Firefox 控制台试试这个;)
  • @georg 我知道未来的 ES 版本正在实现列表推导,但它们没有标准化。问题是 OP 声称它们以前作为标准存在并且已被弃用,这是不正确的。
  • @AndrewLi:这也不正确,理解早在 2015 年之前就已经存在,它们计划用于废弃的 ES4(2007)。
  • @georg 啊,我明白了。我没有意识到这一点。感谢您的信息

标签: javascript recursion


【解决方案1】:

Array comprehensions 是 Mozilla 在 2007 年提出并实现的,作为其“Javascript 1.7”计划的一部分(支持当时即将推出和后来放弃的 ES4),不幸的是他们没有进入当前标准(当然,像Object.getOwnPropertySymbolsOrSomeOtherUnreadableMess() 这样的东西在可编辑性和效率方面更为重要)。所以,在 JS 中,你必须求助于 .map 来处理这种东西:

let list_all = obj => {
   if (!Array.isArray(obj))
        return [obj];
    else
        return [].concat(...obj.map(list_all))
}

【讨论】:

    【解决方案2】:

    在 JavaScript 中,您确实可以使用数组原型方法,如 .map().reduce().some().every().filter(),来完成任务,还可以对数组进行递归调用。在 ES6 中,扩展语法(很像 Python 中的 *)允许将数组转换为函数参数。在 JavaScript 中,数组使用 .concat() 方法而不是 Python 的 + 连接,并且三元运算符比 Python 中的 ... if ... else ... 运算符更常用。

    这是执行您的示例 Python 脚本所做的 ES6 代码:

    function flattenArray(obj) {
        return Array.isArray(obj) 
            ? [].concat(...obj.map(flattenArray)) 
            : [obj];
    }
    // Sample call:
    var res = flattenArray([1,[2,3],[4,[5,6],7],8]);
    
    console.log(res);

    【讨论】:

      【解决方案3】:

      这是一个非常广泛的问题,但总的来说,JavaScript 适合一些非常实用的函数式解决方案。在下面的代码中,我将flatten 定义为一个非常简单的递归过程,它对数组的头部进行简单的案例分析。对我来说,这比其他答案中提供的[].concat 示例读起来更好——而且,Array.prototype.map 没有任何问题,但我认为在这里使用它没有任何好处。

      const flatten = ([x,...xs]) => {
        if (x === undefined)
          return []
        else if (x.constructor === Array)
          return [...flatten(x), ...flatten(xs)]
        else
          return [x, ...flatten(xs)]
      }
      
      let result = flatten([1,[2,3],[4,[5,6],7],8])
      
      console.log(result)
      // [ 1, 2, 3, 4, 5, 6, 7, 8 ]

      但是,如果您想要更深入的答案,我会查看我在此处发布的答案:

      我还有一些关于递归和数组操作的其他答案,可能对你有用

      我希望这些对您有所帮助。如果您有任何问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多