JavaScript 数组的 reduce 辅助方法的扩展使用

3

背景

我正在学习Udemy上的一门课程,该课程涵盖了所有ES6功能。在其中一节课中,讲师谈到使用reduce辅助方法来解决流行的平衡括号面试问题。

我可以不用reduce方法解决这个问题。虽然使用reduce方法可以用更少的代码完成任务。我曾经在面试中被要求找到括号的深度,并想知道是否可以使用reduce在同一个方法中完成所有操作。

我不知道为什么这个问题会让我如此困惑,但我想学习。

问题

我已经尝试了一段时间,可能是因为我不理解reduce的工作原理。

示例

这个示例使用reduce方法返回关于括号是否均匀开放和关闭的true或false。

function balanceParens(string) {
    return !string.split("").reduce((counter, char) => {
        // Handle if parens open and close out of order
        if (counter < 0) { return counter; }
        // Add 1 for each open in order
        if (char === "(") { return ++counter; }
        // subtract 1 for each close in order
        if (char === ")") { return --counter; }
        // handle use case if char is not a paren
        return counter;
    }, 0);
}
console.log(balanceParens("((()))"));

问题

如何使用reduce辅助方法返回括号的最大深度。


实际上,reduce方法是在 ES5 中引入的... - Bergi
如果没有使用 reduce,你会如何解决这个问题?如果你能够发布你的循环代码,我们可以帮助你将其转换为 reduce - Bergi
是的,它是在ES5中引入的。但是这门课程是关于ES6的,这只是他在ES6课程中谈论的一些内容。 - wuno
@Bergi,等我回家后,我可以发布一种不使用reduce的解决方案。但可能需要几个小时。 - wuno
3
通常情况下,如果你有符合.reduce()模式的内容,但需要多个值,则可以将对象用作reduce的目标。 - Pointy
@Bergi TIL reduce 在规范版本5.1中已经存在 :P - Andrew Li
3个回答

3
您可以在减少的同时保持当前深度和最大深度。

function maxDepth(string) {
    return string.split("").reduce(({current, max}, char) => {
        // Handle if parens open and close out of order
        if (current < 0) return {current, max}
        // Add 1 for each open in order
        if (char === "(") return { current: current + 1, max: Math.max(max, current + 1)}
        // subtract 1 for each close in order
        if (char === ")") return { current: current - 1, max}
        return {current, max}
    }, {current: 0, max: 0}).max;
}
console.log(maxDepth("(((()))(((())))()(((((()))))))"));


非常感谢!这太完美了,现在我能看到我的问题了。哎呀,我就差点成功了。 - wuno

1
这是一个简洁的版本,当括号不平衡时返回NaN。它使用嵌套函数以函数式风格编写:

function maxDepth(string) {
    return ( ([depth, max]) => depth ? NaN : max )
        ([...string].reduce(([depth, max], ch) => 
            (newDepth => [newDepth, newDepth < 0 ? NaN : Math.max(max, newDepth)])
                 (depth + (ch === "(") - (ch === ")"))
        , [0, 0]));
}
console.log(maxDepth("(((()))(((())))()(((((()))))))"));


0

这应该能解决问题!

function balanceParens(string) {
    let max = 0;
    let res = string.split("").reduce((counter, char) => {
        // Handle if parens open and close out of order
        if (counter < 0) { 
          return counter;
        }
        // Add 1 for each open in order
        if (char === "(") {
          if(++counter > max) {
            max = counter;
          }
          return counter;
        }
        // subtract 1 for each close in order
        if (char === ")") {
          return --counter;
        }
        // handle use case if char is not a paren
        return counter;
    }, 0);
    console.log("Max depth was :", max);
    return !res;
}
console.log(balanceParens("((()(((())))))((((()))))"));


你是什么意思?“const”变量在哪里? - Aftab Khan
1
我喜欢这个答案。它似乎更符合问题示例。 - Rick
有什么具体的原因吗? - Aftab Khan
@Arrow 在 reducer 之外改变某些状态并不是真正的“一致性” :) - Yury Tarabanko
1
如果有人感兴趣给出详细的答案,可以在这里提问。 - Aftab Khan
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接