上一篇文章我們將JavaScript中數組的方法彙總了一下,本文我們一起來看看JavaScript數組常見的一個問題:數組扁平化。
什麼是數組扁平化
數組扁平化:就是講一個複雜的嵌套多層的數組,一層一層地轉化爲層級較少或者只有一層的數組。
下面我們通過實際例子來看看都有哪些解決方法:
let array = [1, [2, [3, [4, 5]]]]
// 需要將上面的array展開得到下面的一維數組
[1, 2, 3, 4, 5]
歡迎關注我的微信公衆號:前端極客技術(FrontGeek)
flat()
從上一篇文章中我們可以知道,在ES6 新增的flat()方法可以用於將嵌套的數組“拉平”,變成一維的數組。
let array = [1, [2, [3, [4, 5]]]]
array.flat() // [1, 2, [3, [4, 5]]]
但是flat()方法默認只會“拉平”一層,如果不管多少層嵌套,都要轉成一維數組,可以用Infinity
關鍵字作爲參數。
let array = [1, [2, [3, [4, 5]]]]
array.flat(Infinity) // [1, 2, 3, 4, 5]
replace + JSON.parse
除了直接使用上面說的flat()方法,我們還可以通過replace和JSON.parse方法結合將數組扁平化。
我們先利用JSON.stringify將數組轉出JSON字符串,在通過replace方法,利用正則表達式將字符串中的[
、]
替換成掉,再在字符串首尾加上[],最後利用JSON.parse方法將字符串重新轉爲數組。
let array = [1, [2, [3, [4, 5]]]]
let str = JSON.stringify(array) // "[1,[2,[3,[4,5]]]]"
str = str.replace(/(\[|\])/g, '') // "1,2,3,4,5"
str = '[' + str + ']' // "[1,2,3,4,5]"
let arr = JSON.parse(str) // [1, 2, 3, 4, 5]
遞歸
除了上面兩種方法,我們比較容易想到的是循環數組元素,如果元素還是一個數組,就遞歸調用該方法。實現代碼如下:
let array = [1, [2, [3, [4, 5]]]]
function flatten(arr) {
let result = []
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]))
} else {
result.push(arr[i])
}
}
return result
}
console.log(flatten(array)) // [1, 2, 3, 4, 5]
reduce函數迭代
從上面遞歸的方法來看,其實就是對數組進行處理,最終返回一個一維數組,那麼我們可以考慮使用 reduce
來簡化代碼:
let array = [1, [2, [3, [4, 5]]]]
function flatten(arr) {
return arr.reduce(function (prev, next) {
return prev.concat(Array.isArray(next) ? flatten(next) : next)
}, [])
}
console.log(flatten(array)) // [1, 2, 3, 4, 5]
擴展運算符…
ES6 增加了擴展運算符,用於取出參數對象的所有可遍歷屬性,拷貝到當前對象中。
我們先通過下面的例子來看看擴展運算符的用法:
let array = [1, [2, [3, [4, 5]]]]
console.log([].concat(...array)) // [1, 2, [3, [4, 5]]]
我們可以使用擴展運算符對遞歸方法進行修改,具體代碼如下:
let array = [1, [2, [3, [4, 5]]]]
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}
console.log(flatten(array)) // [1, 2, 3, 4, 5]
歡迎關注我的微信公衆號:前端極客技術(FrontGeek)