javascript,

Javascript - Flatten/Merge Array

Tony Tony Follow Nov 06, 2019 · 4 mins read
Javascript - Flatten/Merge Array
Share this

Merge/Flatten Array

在 StackOverflow 上看到了一個經典問題 - Array Flatten ,七年前提問的,但是到15天前還有人回應,引起了我的興趣,那麼就來記錄&實作 Flatten有哪些實現的方法吧。
flatten

Question

原始的題目是這樣的 有一個嵌套的Array如下,現在想要實現一個 Array 解構的方法,消除掉 Array 裡的嵌套 Array。

//Origin:
[["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]]

//After flatten operation
["$6", "$12", "$25", ...]

實現方法

方法1: concat

var arrays = [
  ["$6"],
  ["$12"],
  ["$25"],
  ["$25"],
  ["$18"],
  ["$22"],
  ["$10"]
];
var merged = [].concat.apply([], arrays);

console.log(merged);
//Output
//[
//  "$6",
//  "$12",
//  "$25",
//  "$25",
//  "$18",
//  "$22",
//  "$10"
//]

討論

concat方法的作用是連結兩個以上的陣列,或是將元素增加到我們想要的陣列內容中。

var array1 = ["aaa", "bbb", "ccc"];
var array2 = ["ddd", "eee", "fff"];
console.log(array1.concat(array2));
//Output
// ["aaa", "bbb", "ccc", "ddd", "eee", "fff"]

apply方法的功能是把 Array 解構成一個個的元素後再傳遞給調用函數。

func.apply(thisValue, [arg1, arg2, ...])
// 不考慮thisValue的作用的話,上式與下面的寫法等價
func(arg1, arg2, ...)

也就是說,在解法一中的寫法

[].concat.apply([], [["$6"], ["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"]])
//等價於
["$6"].concat(["$12"], ["$25"], ["$25"], ["$18"], ["$22"], ["$10"])

方法2 Array.prototype.flat()

flat是在 ECMA2019 準標內新增的方法。
使用的方法如下

var newArray = arr.flat([depth]);

其中depth是你想要flatten的層數,預設為1。

以官方的說明舉例:

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

方法3 遞迴

直接上pseudo code

宣告一個array res 存放flatten姞果
Array.forEacch 遍歷目標array
   {
       判斷元素的資料型態是否為Array
       
            遞迴呼叫forEach繼續做flatten
       
            直接把元素加到 res 
   }

實作如下

const deepFlatten = (arr) => {
  const flatList = [];
  arr.forEach(item => {
    Array.isArray(item)
     ? flatList.push(...deepFlatten(item)) // recursive call
     : flatList.push(item)
  });
  return flatList;
Join Newsletter
Get the latest news right in your inbox. We never spam!
Tony
Written by Tony Follow
Hi, I am Tony, the author of Learning Journey blog. I hope you like what I sharing!