JS數組專題1️⃣ ➖ 數組扁平化

1、什麼是數組扁平化

  1. 扁平化,顧名思義就是減小複雜性裝飾,使其事物自己更簡潔、簡單,突出主題。
  2. 數組扁平化,對着上面意思套也知道了,就是將一個複雜的嵌套多層的數組,一層一層的轉化爲層級較少或者只有一層的數組。

Ps: flatten 可使數組扁平化,效果就會以下:數組

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr)); // [1, 2, 3, 4]
複製代碼

從中能夠看出,使用 flatten 處理後的數組只有一層,下面咱們來試着實現一下。app

2、簡單實現

2.1 普通遞歸

  • 這是最容易想到的方法,簡單,清晰!
/* ES6 */
const flatten = (arr) => {
  let result = [];
  arr.forEach((item, i, arr) => {
    if (Array.isArray(item)) {
      result = result.concat(flatten(item));
    } else {
      result.push(arr[i])
    }
  })
  return result;
};

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼
/* ES5 */
function flatten(arr) {
  var result = [];
  for (var i = 0, len = arr.length; i < len; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]))
    }
    else {
      result.push(arr[i])
    }
  }
  return result;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼

2.2 toString()

  • 該方法是利用 toString 把數組變成以逗號分隔的字符串,而後遍歷數組把每一項再變回原來的類型。

先來看下 toString 是怎麼把數組變成字符串的函數

[1, [2, 3, [4]]].toString()
// "1,2,3,4"
複製代碼

完整的展現ui

/* ES6 */
const flatten = (arr) => arr.toString().split(',').map((item) => +item);

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼
/* ES5 */
function flatten(arr) {
  return arr.toString().split(',').map(function(item){
    return +item;
  });
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼

這種方法使用的場景卻很是有限,必須數組中元素所有都是 Number。 也能夠所有都爲 String,具體實現你們本身體會。this

2.3 [].concat.apply + some

  • 利用 arr.some 判斷當數組中還有數組的話,循環調用 flatten 扁平函數(利用 [].concat.apply扁平), 用 concat 鏈接,最終返回 arr;
/* ES6 */
const flatten = (arr) => {
  while (arr.some(item => Array.isArray(item))){
    arr = [].concat.apply([], arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼
/* ES5 */
/** * 封裝Array.some * @param {function} callback - 回調函數 * @param {any} currentThis - 回調函數中this指向 */
Array.prototype.some = function (callback, currentThis){
  let context = this;
  let flag = false;
  currentThis = currentThis || this;
  for (var i = 0, len = context.length; i < len; i++) {
    const res = callback.call(currentThis, context[i], i, context);
    if (res) {
      flag = true;
    } else if (!flag) {
      flag = false;
    }
  }
  return flag;
}

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

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼

2.4 reduce

  • reduce 自己就是一個迭代循環器,一般用於累加,因此根據這一特色有如下:
function flatten(arr){
  return arr.reduce(function(prev, cur){
    return prev.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼

2.5 ES6 中的 解構運算符 ...

  • ... 每次只能展開最外層的數組,被 [].concat 後,arr 就扁平化一次。
function flatten(arr){
  while(arr.some(item => Array.isArray(item))){
    arr = [].concat(...arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
複製代碼

番外篇將給你們講解 lodashflatten 的實現源碼,感謝你們閱讀!spa

相關文章
相關標籤/搜索