在JavaScript中进行递归的最佳方法?

时间:2017-03-19 20:16:35

标签: javascript recursion

我主要用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是列表推导的良好替代吗?如果没有,那又怎样?

3 个答案:

答案 0 :(得分:4)

Mozilla提出并实施了

Array comprehensions作为他们的“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))
}

答案 1 :(得分:1)

在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);

答案 2 :(得分:0)

这是一个非常广泛的问题,但总的来说,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 ]

但是,如果你想要一个更深入的答案,我会看一下我在这里发布的答案:

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

我希望你发现这些有用。如果您有任何疑问,请与我们联系。