JS專題之數組展開

前言

首先什麼是數組展開?
假如如今有這樣一個需求:將後臺的一個多重 List 數據,展開成一個 List 後,並去重後排序;javascript

["a", "b", ["c", "d"], [["d"],"e"], "f"] => ["a", "b", "c", "d", "e"];
複製代碼

數組去重咱們前面在《JS專題之數組去重》已經講過了,那麼前一步的多重數組展開成單層數組,該如何處理呢?java

這就來到咱們所要探討的數組展開了。
根據需求的特色,數組展開須要進行迭代和遞歸。數組

回答文章開頭的問題:閉包

將多重數組轉化成單層數組的過程就是數組展開,也叫做數組扁平化(flatten)app

1、循環加遞歸

最簡單的思路:循環中判斷,若是子元素是數組則遞歸。函數

function flatten(origin) {
    var result = [];
    for(var i = 0; i< origin.length; i++) {
        var item = origin[i];
        if(Array.isArray(item)) {
            result = result.concat(flatten(item))
        } else {
            result.push(item);
        }
    }
    return result;
}

var arr = ["a", "b", ["c", "d"], [["d"],"e"], "f"];
flatten(arr);  // ["a", "b", "c", "d", "d", "e", "f"]
複製代碼

2、toString()

數組的原型對象上有一個方法,toString, 它能把數組的因此元素轉化成用逗號隔開的字符串。post

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
arr.toString()  // "1,2,3,4,a,b,c,d,d,e,f"

// 因此,利用 split 先把字符串轉化爲單層數組,再進行處理。
const flatten = (origin) => origin.toString().split(',');  // ["1", "2", "3", "4", "a", "b", "c", "d", "d", "e", "f"]
複製代碼

因爲 toString 轉化爲字符串的時候,不會區分字符串和數字類型,在進行區分數據類型的時候要注意。ui

3、split

上面的方法,咱們用 toString() 將數組轉化爲字符串,那麼咱們也能夠用 split 來作:this

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];
function flatten(arr) {
    return arr.join(',').split(',');  
} 
console.log(flatten(arr))。 // ["1", "2", "3", "4", "a", "b", "c", "d", "d", "e", "f"]
複製代碼

一樣,這種字符串和數組互轉的過程,不適合多種數據類型同時處理。spa

4、reduce

咱們注意到其實數組扁平化其實就是「迭代 + 拼接(累加) + 遞歸」的過程,數組 reduce 方法既能夠迭代又能夠累加,適合作數組扁平化。

function flatten(origin){
  return origin.reduce(function(init, item){
    return init.concat(Array.isArray(item) ? flatten(item) : item)
  }, [])
}
var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]
複製代碼

5、some + concat

some 會遍歷數組的每個元素,判斷是否有元素都知足條件,最後返回布爾值。some 一旦返回真值後,其後的元素就不會繼續監測。

function flatten(origin) {
    while (origin.some(item => Array.isArray(item))){
    origin = [].concat.apply([], origin);
  }
  return origin;
}
var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]
複製代碼

6、some + 擴展運算符

ES6 擴展運算符...能夠將兩重數組轉換爲單層數組:

[].concat(...[1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"]);  // [1, 2, 3, Array(1), "a", "b", "c", "d", Array(1), "e", "f"]

// 利用 some 方法,咱們能夠實現多重轉換爲單層:

function flatten(origin) { while(origin.some(item=> Array.isArray(item))) {
        origin = [].concat(origin);
    } return origin;
}

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];  
console.log(flatten(arr)) // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"]
複製代碼

7、原生 flat

JS Array 對象提供了原生的能夠實現扁平化的函數flat:詳細說明見 MDN

var arr = [1, [2, 3, [4]], "a", "b", ["c", "d"], [["d"],"e"], "f"];
// 2 表示深度
arr.flat(2)  // [1, 2, 3, 4, "a", "b", "c", "d", "d", "e", "f"];

複製代碼

總結

數組扁平化其實就是利用元素迭代 + 元素拼接(疊加)+ 遞歸調用來對數組進行處理,達到將多層數組轉換爲單層數組的過程。 歡迎關注個人我的公衆號「謝南波」,專一分享原創文章。

掘金專欄 JavaScript 系列文章

  1. JavaScript之變量及做用域
  2. JavaScript之聲明提高
  3. JavaScript之執行上下文
  4. JavaScript之變量對象
  5. JavaScript之原型與原型鏈
  6. JavaScript之做用域鏈
  7. JavaScript之閉包
  8. JavaScript之this
  9. JavaScript之arguments
  10. JavaScript之按值傳遞
  11. JavaScript之例題中完全理解this
  12. JavaScript專題之模擬實現call和apply
  13. JavaScript專題之模擬實現bind
  14. JavaScript專題之模擬實現new
  15. JS專題之事件模型
  16. JS專題之事件循環
  17. JS專題之去抖函數
  18. JS專題之節流函數
  19. JS專題之函數柯里化
  20. JS專題之數組去重
  21. JS專題之深淺拷貝
相關文章
相關標籤/搜索