JS 扁平化 (flatten) 陣列

稻草叔叔發表於2019-02-19

前言

陣列是 JS 中使用頻率僅次於物件的資料結構,官方提供了眾多的 API,談談如何扁平化(flatten)陣列。

陣列的扁平化,是將一個巢狀多層的陣列 array (巢狀可以是任何層數)轉換為只有一層的陣列

flat

flat(depth) 方法會遞迴到指定深度將所有子陣列連線,並返回一個新陣列, depth指定巢狀陣列中的結構深度,預設值為1,不管多少層則可以用Infinity關鍵字作為引數

[1, 2, [3]].flat(1) // [1, 2, 3]

[1, 2, [3, [4]]].flat(2) // [1, 2, 3, 4]

[1, 2, [3, [4, [5]]]].flat(Infinity) // [1, 2, 3, 4, 5]
複製程式碼

flat()有相容性問題, 不建議使用

reduce

function flatten(arr) {
  return arr.reduce((a, b) => {
    // return Array.isArray(b) ? a.concat(flatten(b)) : a.concat(b);
    return a.concat(Array.isArray(b) ? flatten(b) : b);
  }, []);
};

// es6
const flatten = arr =>
  arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);


flatten([1,[2,3],4,[[5,6],7]])  // [1, 2, 3, 4, 5, 6, 7]
複製程式碼

toString

只適於陣列的元素都是數字

function flatten(arr) {
  return arr.toString().split(",").map(item => +item);
};


flatten([1,[2,3],4,[[5,6],7]])  // [1, 2, 3, 4, 5, 6, 7]
複製程式碼

[].concat(...arr)

function flatten(arr) {
  return !Array.isArray(arr) ? arr : [].concat.apply([], arr.map(flatten));
}


flatten([1,[2,3],4,[[5,6],7]])  // [1, 2, 3, 4, 5, 6, 7]
複製程式碼

generator

function* flatten(arr) {
  if (!Array.isArray(arr)) yield arr;
  else for (let el of arr) yield* flatten(el);
}

let flattened = [...flatten([1,[2,[3,[4]]]])];  // [1, 2, 3, 4]
複製程式碼

字串過濾

將輸入陣列轉換為字串並刪除所有括號([])並將輸出解析為陣列

const flatten = arr => JSON.parse(`[${JSON.stringify(arr).replace(/\[|]/g,'')}]`);
複製程式碼

undercore or lodash 庫

使用undercore庫或者lodash的中_.flatten函式,具體用法查閱API文件

_.flatten([1, [2], [3, [[4]]]]);
=> [1, 2, 3, 4];
複製程式碼

參考文獻

實現扁平化(flatten)陣列的方法還有很多種,可以參考一下文獻

  1. javascript-flattening-an-array-of-arrays-of-objects

  2. merge-flatten-an-array-of-arrays-in-javascript

相關文章