用 reduce 確認括號是否成對

前言

在網路上搜尋 Array.reduce() 用法時,最常看到的就是數字加總。但既然這是 ES6 新加的陣列操作方式,總不可能就只拿來做數字運算吧! 後來找到了一個應用題,就拿來試試 reduce 解題吧!

題目說明

寫出一個函式,檢查括號是否左右成對。成對則回傳 true ,否則回傳 false。相關範例如下:

1
2
3
4
5
6
7
8
// return true
'()()'
'(())'

// return false
'())'
'(()'
')('

解題

  • 先把傳入字串一個一個拆開成陣列,然後用 reduce 迭代陣列中的每個項目。

    1
    2
    3
    function balanceParens(string) {
    string.split('').reduce()
    }
  • 用數字表達括號的成對狀況。設定初始值為 0,遇到左括號 +1、遇到右括號 -1

    1
    2
    3
    4
    5
    6
    function balanceParens(string) {
    string.split('').reduce((previous, char) => {
    if (char === '(') { previous++ }
    if (char === ')') { previous-- }
    }, 0)
    }
  • 檢查 reduce 回傳值,如果為 0 (左右括號數量相同),則回傳 true,否則回傳 false

    1
    2
    3
    4
    5
    6
    7
    8
    function balanceParens(string) {
    return !string.split('').reduce((previous, char) => {
    if (char === '(') { previous++ } // '('
    if (char === ')') { previous-- } // ')'

    return previous // '()' 以外文字,例: a, b, c
    }, 0)
    }
  • 檢查成對時,左右括號不能順序相反,也就是過程中不能出現負值。

    1
    2
    3
    4
    5
    6
    7
    8
    function balanceParens(string) {
    return !string.split('').reduce((previous, char) => {
    if (char === '(') { previous++ }
    if (char === ')') { previous-- }

    return previous < 0 || previous
    }, 0)
    }

重構函式

到目前為止的流程就可以確實完成所有檢查動作了,但感覺可以讓流程變得更直覺一些。整個流程只會處理 4 種狀況:

  1. 遇到 (
  2. 遇到 )
  3. 遇到其他字符,例如: abc
  4. 數值小於 0

如果能讓每種狀況都直接 return 結果,整個流程就能更一目瞭然。

1
2
3
4
5
6
7
8
9
function balanceParens(string) {
return !string.split('').reduce((previous, char) => {
if (previous < 0) return previous // 過程中數值小於 0
if (char === '(') return ++previous // 遇到 '('
if (char === ')') return --previous // 遇到 ')'

return previous // 遇到其他字符
}, 0)
}

文章內容如有錯誤,歡迎留言討論!


本 Blog 上的所有文章除特别聲明外,均採用 CC BY-SA 4.0 協議 ,轉載請註明出處!