# 数组扁平化

# concat 特点

var alpha = ['a', 'b', 'c'];

var alphaNumeric = alpha.concat(1, [2, 3]);

console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3]

concat()方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

  • 参数可以有多个
  • 某个参数为数组时,将会被展开后进行合并

# 递归

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]));
    } else {
      result.push(arr[i]);
    }
  }
  return result;
}
flatten(arr);

# reduce 迭代

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
  }, []);
}
console.log(flatten(arr));

# 扩展运算符

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  while (arr.some(item => Array.isArray(item))) {
    // 如果有某一项为数组,则利用concat特性,先展开再合并。
    // 因为concat默认会展开参数为数组的参数再合并。
    arr = [].concat(...arr);
  }
}
console.log(flatten(arr));

# split + toString

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  // 数组对象重写了的toSting和Object的不同
  // Array.prototype.toString() 返回一个字符串,表示指定的数组及其元素。
  // [1, [2, [3, 4, 5]]].toString() -> "1,2,3,4,5"
  return arr.toSting().split(',');
}
console.log(flatten(arr));

# ES6 的 flat

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  // flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
  // 如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。
  return arr.flat(Infinity);
}
console.log(flatten(arr));

# JSON + 正则

var arr = [1, [2, [3, 4, 5]]];
function flatten(arr) {
  let str = JSON.stringify(arr);
  str = str.replace(/(\[|\])/g, '');
  str = '[' + str + ']';
  return JSON.parse(str);
}
console.log(flatten(arr));