首頁 >web前端 >js教程 >JavaScript專題之八:陣列扁平化

JavaScript專題之八:陣列扁平化

coldplay.xixi
coldplay.xixi轉載
2021-03-11 09:42:242346瀏覽

JavaScript專題之八:陣列扁平化

目錄

  • 一、遞歸
  • 二、reduce
  • ##三、apply some
  • 四、ES6展開運算子
  • 五、toString
  • 六、正規
  • 七、實作自己的扁平化工具方法
  • 寫在最後

JavaScript專題之八:陣列扁平化

(免費學習推薦:javascript影片教學 #)

一、遞迴

for迴圈是我們在進行陣列運算時最容易想到的,在不考慮時間和空間複雜度的時候,遞歸應該是完美的選擇!

範例:

输入 
const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];`
输出 
[ 1, 2, 3, 4, { a: 1 }, null, undefined ]

程式碼:

function flatten(arr) {
    let res = [];
    for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            // 因为函数返回的是数组,所以要做拼接处理
            res = res.concat(flatten(arr[i]));
        } else {
            res.push(arr[i])
        }
    }
    return res;}

注意:

    判斷數組內元素的基本類型
  1. 如果不是數組:直接存入新數組中
  2. 如果是數組:重複第一步,直到將最後一個不是數組的元素存入到新數組中

二、reduce

#先來看看

reduce是做什麼的:reduce( ) 方法對陣列中的每個元素執行一個由您提供的reducer函數(升序執行),將其結果匯總為單一傳回值。

範例:

输入 
const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];`
输出 
[ 1, 2, 3, 4, { a: 1 }, null, undefined ]

程式碼:

function flatten(arr) {
    return arr.reduce((prev, next) => {
        // prev表示上一次操作的结果
        return prev.concat(Array.isArray(next) ? flatten(next) : next)
    }, [])
    // 注意reduce的初始值应该是[],否则无法进行拼接}

注意:

仔細對照

方法一方法二,兩者思路完全一致-找到資料型態是陣列的子元素,對其進行抹平處理,只不過實現的細節略有不同。

唯一要注意的地方就是拼接時資料的基本型別要以陣列開始。

三、apply some

既然方法二是方法一的變式,那個方法三也可以說是方法二的變式,但不在採用遞歸的方式,而是一層一層「拆除」嵌套的方式

先來看看用到的API:

  • apply:呼叫一個具有給定this值的函數,以及以一個陣列(或類別數組物件)的形式提供的參數。
  • some:測試數組中是否至少有1個元素通過了被提供的函數測試。它回傳的是一個Boolean型別的值

#程式碼:

function flatten(arr) {
    while (arr.some(item => Array.isArray(item))) {
        // 只要存在数组类型的元素,就抹平一层
        arr = [].concat.apply([], arr)
    }
    return arr;}

注意:

大家疑惑的點主要在

apply,其實主要目的就是減少括號

let res = [];res  = res.concat({});// 等价于[].concat.apply([], [{}])
在本例中:

arr = [].concat.apply([], arr);// 等价于[].concat(1, [2, [3, 4, { a: 1 }], null], undefined)

四、ES6展開運算子

大家可能業也注意到了,方法一到方法三我們不斷的借助現有方法,以精簡我們的程式碼量,本方法也是如此~

我們利用ES6的展開運算子(用於取出參數物件的所有可遍歷屬性,拷貝到目前物件之中),繼續精簡方法三:

程式碼:

function flatten(arr) {
    while (arr.some(item => Array.isArray(item))) {
        // 只要存在数组类型的元素,就抹平一层
        arr = [].concat(...arr)
    }
    return arr;}
五、 toString

如果前面四個方法是我們可以實現的主流的方式,那麼接下來的幾個就是我們可以實現的「非主流」方​​式,直接上程式碼!

function flatten(arr) {
    return arr.toString().split(',').map(function(item){
        return +item    })}
注意:

將資料轉換型別存在類型的限制,如果原始資料是這樣的:[1, '2'],那麼就會出現問題

六、正規

假如我們預設了型別會被轉換這個缺陷,那麼還可以用更暴力裡的方式來平整陣列:

function flatten(arr) {
    return JSON.stringify(arr).replace(/\[|\]/g, '').split(',');}
注意:

如果是純數組,似乎沒什麼問題

function flatten(arr) {
    return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '').split(',') + ']')}
但如果數組內存在對象,就需要消除JSON後的後果,這樣更嚴謹一些~

到這裡,六種方法算是包括了大部分數組扁平化的實現,那麼如果希望將我們的方法「升級」成工具怎麼辦?這時候我們就要「抄襲」一下loadsh了~

JavaScript專題之八:陣列扁平化

#七、實作自己的扁平化工具方法

這裡我們簡化了loadsh裡的flatten函數,具體改動我們來看程式碼:
     /*
     * @private
     * @param {Array} array 需要扁平化的数组
     * @param {number} depth 最多处理几层
     * @param {boolean} [isStrict] 是否严格处理函数
     * @param {Array} [result=[]] 输出的数组
     * @returns {Array}
     */function flatten(array, depth, isStrict, result) {
        result || (result = [])
        // 边界
        if (array == null) return result;
    
        for (const value of array) {
            if (depth > 0 && Array.isArray(value)) {
                if (depth > 1) {
                    flatten(value, depth - 1, isStrict, result)
                } else {
                    result.push(...value); // 只拆1层
                }
            } else if (!isStrict) {
                result[result.length] = value        }
        }
        return result;}
  1. 該方法提供了扁平化層數
    const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, false);// [ 1, 2, 3, 4, [ 5, 6 ], { a: 1 }, null, undefined ]
  1. 該方法提供了扁平化後相反的效果

const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, true);// [ 3, 4, [ 5, 6 ] ]const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 2, true);// [ 5, 6 ]
isStrict參數打開後,扁平後保留了被暴漏出來的元素,剔除了淺層元素。

寫到這裡我們即了解了扁平化的處理思路,也有了一定的實現能力,如果你能完全理解上面的程式碼,相信扁平化這一部分應該難不到你了,我們下一篇文章繼續研究loadsh的另一個方法~

相關免費學習推薦:javascript##(影片)

以上是JavaScript專題之八:陣列扁平化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除