灏天阁

ES6查漏补缺【数组的扩展】

· Yin灏

1. 先简单复习一下 ES5 中的数组方法

改变原数组的:
	添加: push / unshift
	删除: pop / shift
	任意位置的添加 或 删除: splice(startIndex,delCount, ...addElement)
	翻转: reverse
	排序: sort
不改变原数组的:
	indexOf / lastIndexOf: 只能检索基本类型,不能检索复杂类型(引用类型)
	cancat(arr1, arr2, ...)
	join(str)

在这里插入图片描述 答案:除了 A 都可以

2.静态方法

ES5:Array.isArray()

  • typeof:只能用于检测基本类型,不能用来检测引用类型
  • 作用: 检测一个 变量/数据 是不是 数组(类型)
  • 返回: 如果是数组(类型),返回 true;否则返回 false
const array = ["Webpack", "ES6", "TypeScript", "React"];
const obj = {};

console.log(typeof array); //object
console.log(typeof obj); //object

console.log(Array.isArray(array)); // true
console.log(Array.isArray(obj)); // false

ES6:array.from()

  • 作用:
    • 把一个类(假/伪)数组 转成 真数组,
    • 如果传入了回掉函数,可以对遍历的结果做进一步处理,
    • 并会用回掉函数 返回的结果 作为 新数组的成员
  • 例如:
    • 1.document.querySelectorAll()/document.getElementsByTagName()
    • 2.arguments
  • 返回:
    • 转好之后的 真数组
function fn() {
  console.log(arguments); // 伪数组
  console.log(Array.from(arguments)); // 真数组
  let arr = Array.from(arguments, (item, index) => item * 2);
  console.log(arr); // 返回一个新数组
}
fn(1, 2, 3, 4, 5, 6);

在这里插入图片描述

ES6:array.of()

  • 作用:把一堆零散的数据,转成一个数组返回
  • 返回:转换好的数组
console.log(Array.of('零散', '数组', '返回')) //(3) ['零散', '数组', '返回']

3.数组实例方法

includes(el)

  • 作用:判断 el 这个元素在不在数组中,用来取代 indexOf/lastindexOf 两个方法, 相比之下 includes 更具语义化,通常陪着 if 语句使用
  • 注意:因为 includes 内部是通过三个等号判断的,因此它只能判断基本类型, 不能判断引用类型
  • 返回:如果在,返回 true;否则返回 false

基本类型

const beauty = ["剑圣", "魔神", "元素", "缔造"];

// indexOf
console.log(beauty.indexOf("魔神")); // 1
console.log(beauty.indexOf("柔道")); // -1

// includes 内部通过 === 来判断,所以只能是基本类型
console.log(beauty.includes("魔神")); // true
console.log(beauty.includes("柔道")); // false

引用类型

const boys = [
  {
    name: "地下城",
    from: "腾讯",
  },
];

console.log(
  {
    name: "地下城",
    from: "腾讯",
  } ===
    {
      name: "地下城",
      from: "腾讯",
    }
); // false 因为内存指向不同

console.log(
  boys.includes({
    name: "地下城",
    from: "腾讯",
  })
); //false

在这里插入图片描述

fill()

  • 作用:用一个固定值,替换/填充数组的元素,会改变原数组
  • 语法:array.fill(value, startIndex = 0, endIndex = arr.length])

基本类型

const beauty = ["剑圣", "魔神", "元素", "缔造"];

// 全部替换
console.log(beauty.fill("地下城")); // (4) ['地下城', '地下城', '地下城', '地下城']
console.log(beauty.includes("地下城")); // 所以为true

// 替换前两个
console.log(beauty.fill("柔道", 0, 2)); // (4) ['柔道', '柔道', '地下城', '地下城']

引用类型

const boys = [
  {
    name: "地下城",
    from: "腾讯",
  },
  {
    name: "穿越火线",
    from: "腾讯",
  },
];

boys.fill({
  name: "学习",
  from: "天天向上",
});

console.log(boys);

// 创建一个数组长度为5,元素都是地下城的数组
console.log(Array(5).fill("地下城")); // 新增
console.log(new Array("q", "c", "m").fill("勇士")); // 替换数组中的元素

// 对象形式
console.log(
  Array(5).fill({
    name: "学习",
    from: "天天向上",
  })
); // 新增

console.log(
  new Array("q", "c", "m").fill({
    name: "学习",
    from: "天天向上",
  })
); // 替换数组中的元素

在这里插入图片描述

filter()

  • 作用:用指定条件,对数组进行过滤/筛选,留下一部分,去掉一部分
  • 返回:满足条件的新数组
  • 语法: array.filter((value, index, arr) => { 回调的参数和 forEach 的回调参数是一样的 return true,回调返回 true,则当前 value 会放入到返回的新数组中 return false, 回调返回 false, 则当前 item 不会放到返回的新数组中 })

基本类型

// 中文
const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];
// 1.找出姓为库的人
const result = names.filter((value) => value.startsWith("库")); // index 和 arr不用的话去掉

console.log(result); // ['库里', '库春野']
console.log(names); // ['杜兰特', '库里', '巴特勒', '科比', '乔丹', '库春野'] 数组本身不变
// 数字
const waislines = [20, 40, 19, 70, 105, 60];
// 找出腿长小于60的人并升序排序
const result = waislines.filter((value) => value < 60).sort((a, b) => a - b);
console.log(result); // [19, 20, 40]
console.log(waislines); // 原数组 [20, 40, 19, 70, 105, 60]

引用类型

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的
const result = boys.filter((value) => value.height > 200);
console.log(result);
console.log(boys); // 原数组不变

在这里插入图片描述

手写一个 _filter()

// 手写一个 _filter()
Array.prototype._filter = function (callback) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    if (callback(this[i], i, this)) {
      result.push(this[i]);
    }
  }
  return result;
};

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的
const result = boys._filter((value) => value.height > 200);
console.log(result);
console.log(boys); // 原数组不变

在这里插入图片描述

find()

  • 作用:根据指定条件,对数组进行查找
  • 返回:如果找到了,返回第一个满足条件的元素;否则返回 undefined
  • 语法:array.find((value, index, arr) => { return true, 表示 value 符合条件, 返回 value,就此结束查找 return false, 则当前 value 不符合条件, 继续查找 })
  • 结论:跟 filter 一样,但只返回符合条件的第一个值,不返回数组

基本类型

const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];
// 1.找出姓为库的第一个人
const result = names.find((value) => value.startsWith("库")); // index 和 arr不用的话去掉
const result2 = names.find((value) => value.startsWith("李"));

console.log(result); // 库里
console.log(result2); // undefined
console.log(names); // ['杜兰特', '库里', '巴特勒', '科比', '乔丹', '库春野'] 数组本身不变
// 数字
const waislines = [20, 40, 19, 70, 105, 60];
// 找出腿长小于60的第一个人
const result = waislines.find((value) => value < 60);
console.log(result); // 20
console.log(waislines); // 原数组不变 [20, 40, 19, 70, 105, 60]

引用类型

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的第一个人
const result = boys.find((value) => value.height > 200);
console.log(result);
console.log(boys); // 原数组不变

在这里插入图片描述

手写一个 _find()

// 手写一个 _find()
Array.prototype._find = function (callback) {
  for (let i = 0; i < this.length; i++) {
    if (callback(this[i], i, this)) {
      return this[i];
    }
  }
  return undefined;
};

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的
const result = boys._find((value) => value.height > 200);
console.log(result);
console.log(boys); // 原数组不变

在这里插入图片描述

findIndex()

  • 作用:根据指定条件,对数组进行查找
  • 返回:如果找到了,返回第一个满足条件的元素下标;否则返回 -1
  • 语法:array.findIndex((value, index, arr) => { return true, 表示 value 符合条件, 返回 value 在数组中的下标,结束查找 return false, 则当前 value 不符合条件, 继续查找 })

基本类型

// 文字
const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];
// 1.找出姓为库的第一个人的下标
const result = names.findIndex((value) => value == "巴特勒"); // index 和 arr不用的话去掉
const result2 = names.findIndex((value) => value.startsWith("李"));

console.log(result); // 2
console.log(result2); // -1
console.log(names); // ['杜兰特', '库里', '巴特勒', '科比', '乔丹', '库春野']
// 数字
const waislines = [20, 40, 19, 70, 105, 60];
// 找出腿长小于60的第一个人的数组下标
const result = waislines.findIndex((value) => value < 60);
console.log(result); // 20
console.log(waislines); // 原数组 [20, 40, 19, 70, 105, 60]

引用类型

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的第一个人的下标
const result = boys.findIndex((value) => value.height > 200);
const result2 = boys.findIndex((value) => value.height > 300);
console.log(result);
console.log(result2); // -1

在这里插入图片描述

手写一个 _findIndex()

// 手写一个 _find()
Array.prototype._findIndex = function (callback) {
  for (let i = 0; i < this.length; i++) {
    if (callback(this[i], i, this)) {
      return i;
    }
  }
  return -1;
};

// 筛选对象
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 找到身高两米以上的第一个人的下标
const result = boys._findIndex((value) => value.height > 200);
const result2 = boys._findIndex((value) => value.height > 300);
console.log(result);
console.log(result2); // -1
console.log(boys); // 原数组不变

在这里插入图片描述

map()

  • 作用:映射,根据已有的数组得到一个新数组,两者数组元素是一一对应的
  • 返回:映射后的新数组
  • 语法:array.map((item,index,arr) => { return 新的值;// 把每次回调函数中返回的新值,加到新数组中 })

基本类型

// 文字
const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];
// 1.把每个名字后面都拼上编号
const result = names.map((value, index) => value + index); // 返回一个新的数组
console.log(result, "新数组");
console.log(names, "原数组");

// 数字都加10
const ages = [15, 18, 17, 20, 50, 45];
const result2 = ages.map((value) => value + 10); // 返回一个新的数组
console.log(result2, "新数组");
console.log(ages, "原数组");

在这里插入图片描述

引用类型

// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 给每个对象添加id (下标 + 1)和 是性别属性
const result = boys.map((value, index) => {
  return {
    ...value,
    id: index + 1,
    gender: "female",
  };
});

console.log(result, "新数组"); // 得到的新数组
console.log(boys, "原数组"); // 原数组不变

在这里插入图片描述

手写一个 _map()

Array.prototype._map = function (callback) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    result.push(callback(this[i], i, this));
  }
  return result;
};

// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 给每个对象添加id (下标 + 1)和 性别属性
const result = boys._map((value, index) => {
  return {
    ...value,
    id: index + 1,
    gender: "female",
  };
});

console.log(result, "新数组"); // 得到的新数组
console.log(boys, "原数组"); // 原数组不变

在这里插入图片描述

every()

  • 作用:检测/判断 数组中的所有元素是否满足指定条件
  • 返回:如果都满足,返回 true,否则(只要有一个不满足)返回 false
  • 执行流程:检测到了一个不满足条件的就停止了,否则继续检测
  • 语法:array.every((item, index, arr) => { return 布尔值; return false: 表示 value 不符合条件,停止执行 return true:表示 value 符合条件,继续检查下一个; })
  • 注意:空数组调用 every 会得到一个 true 的结果[].every(()=>{}) //true

基本类型

// 文字
const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];
// 1.检测数组中是否都是姓杜的
const result = names.every((value) => value.startsWith("杜"));
console.log(result, "检测数组中是否都是姓杜的"); // false,检测数组中是否都是姓杜的

// 2.检测数组中是否都不是姓李的
const result2 = names.every((value) => !value.startsWith("李"));
console.log(result2, "检测数组中是否都不是姓李的"); // true,检测数组中是否都不是姓李的
const ages = [15, 18, 17, 20, 50, 45];
// 检测数组中年龄是否都是20以上的
const result = ages.every((value) => value > 20);
console.log(result, "检测数组中年龄是否都是20以上的"); //false 检测数组中年龄是否都是20以上的

// 检测数组中年龄是否都是10以上的
const result2 = ages.every((value) => value > 10);
console.log(result2, "检测数组中年龄是否都是10以上的"); //true 检测数组中年龄是否都是10以上的

引用类型

// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 判断数组中的身高是否都大于200cm
const result = boys.every((value) => value.height > 200);
console.log(result); // false

// 判断数组中的身高是否都大于190cm
const result2 = boys.every((value) => value.height > 190);
console.log(result2); // true

手写一个 _every()

// every方法的原理
Array.prototype._every = function (callback) {
  for (let i = 0; i < this.length; i++) {
    // 如果我们实例不符合条件
    if (!callback(this[i], i, this)) {
      return false;
    }
  }
  // 否则都符合条件
  return true;
};
// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 判断数组中的身高是否都大于200cm
const result = boys._every((value) => value.height > 200);
console.log(result); // false

// 判断数组中的身高是否都大于190cm
const result2 = boys._every((value) => value.height > 190);
console.log(result2); // true

some()

  • 作用:检测判断数组中是否存在满足指定条件的值
  • 返回:如果存在,则返回 true,否则(都不满足条件)返回 false
  • 执行流程:检测到一个满足条件的就停止了,否则继续检测
  • 语法: array.some((value, index, arr) => { return 布尔值 return true:表示 value 符合条件,返回 true return false:表示 value 不符合条件,继续检测 })

基本类型

// 文字
const names = ["杜兰特", "库里", "巴特勒", "科比", "乔丹", "库春野"];

// 1.检测数组中是否有姓杜的,他首次出现的位置在第几个
const result = names.some((value, index) => {
  console.log(value.startsWith("杜"), index + 1); // true 1

  // 如果返回true,就不会再往下找了
  return value.startsWith("杜");
});

console.log(result); // true
// 数字
const ages = [15, 18, 17, 20, 50, 45];
// 检测数组中年龄20以上的是否存在
const result = ages.some((value) => {
  console.log(value);
  return value > 20;
});
console.log(result); // true

在这里插入图片描述

引用类型

// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// // 判断数组中的身高是否都大于200厘米
const result = boys.some((value) => {
  console.log(value.height); // 200 192 205
  return value.height > 200;
});
console.log(result); // true

手写一个 _some()

// some方法的原理
Array.prototype._some = function (callback) {
  for (let i = 0; i < this.length; i++) {
    // 如果我们实例不符合条件
    if (callback(this[i], i, this)) {
      return true;
    }
  }
  // 否则都符合条件
  return false;
};
// 操作的数组
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// // 判断数组中的身高是否都大于200cm
const result = boys._some((value) => {
  console.log(value.height); // 200 192 205
  return value.height > 200;
});
console.log(result); // true

reduce()

reduce(callback, [initiaIValue])

  • 作用:汇总,根据已有的数组得到一个最终(整体)的结果,比如:对数组进行求和

  • 返回:汇总的(整体)结果

  • 两个参数 array.reduce((accumulator, currentValue, currentIndex, array)={ accumulator: 累加器 currentValue: 当前数组中的元素 currentIndex: 当前元素在数组中的下标 array: 数组对象本身 },[initialValue])

      initiaIValue: 可选参数,会影响accumulator的初始值
      如果没给initiaIValue
      那么accumulator取自数组中第一个元素
      此时cuurentValue会取自数组中的第二个元素,开始迭代
    
      如果给定了initiaIValue
      那么initiaIValue回作为accumulator的初始值
      此时currentValue会取自数组中的第一个元素,开始迭代
    

基本类型

  • 没有初始值
// 对数组中的数字进行求和
const waistlines = [55, 43, 70, 58];
const result = waistlines.reduce((accu, cur, index, arr) => {
  console.log(accu, cur, index, arr); // 因为我们没给定initiaIValue所以accu作为初始值开始
  // 55 43 1 (4) [55, 43, 70, 58]
  // 98 70 2 (4) [55, 43, 70, 58]
  // 168 58 3 (4) [55, 43, 70, 58]

  // 如果return的话,accu的值源于上一次返回的值,否则第二次accu为undefined
  return accu + cur;
});
console.log(result); // 226
  • 有初始值
// 对数组中的数字进行求和
cconst waistlines = [55, 43, 70, 58]
const result = waistlines.reduce((accu, cur, index, arr) => {
    console.log(accu, cur, index, arr) // 我们给了初始值的情况
    // 0 55 0 (4) [55, 43, 70, 58]
    // 55 43 1 (4) [55, 43, 70, 58]
    // 98 70 2 (4) [55, 43, 70, 58]
    // 168 58 3 (4) [55, 43, 70, 58]

	// 如果return的话,accu的值源于上一次返回的值
    return accu + cur
}, 0)
console.log(result) // 226

小结:什么时候可以不用给定初始值? 纯数字求和、求积

引用类型

  • 没有初始值
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 不加初始值的情况
const result = boys.reduce((accu, cur) => {
  // 第一次:200 + 192
  // 第二次:392.height + 205
  // 第三次:NaN + 233
  return accu.height + cur.height;
});
console.log(result); // NaN
  • 有初始值
// 引用类型,求平均身高
const boys = [
  {
    name: "杜兰特",
    height: 200,
  },
  {
    name: "库里",
    height: 192,
  },
  {
    name: "巴特勒",
    height: 205,
  },
  {
    name: "科比",
    height: 233,
  },
];

// 加上初始值的情况
const result = boys.reduce((accu, cur, index) => {
  // 第一次:0 + 200
  // 第二次:200 + 192
  // 第三次:392 + 205
  // 第四次:597 + 233
  return accu + cur.height;
}, 0);
console.log(result / boys.length); // 207.5

小结:什么时候必须给初始值? 数组中放的是对象求和(汇总)

解决实际需求

  • 根据数组[‘73’, ‘32’, ‘108’, ‘111’, ‘118’, ‘101’, ‘32’, ‘106’, ‘105’, ‘110’] 求出 ASCII 码字符串
const ASCII = [
  "73",
  "32",
  "108",
  "111",
  "118",
  "101",
  "32",
  "106",
  "105",
  "110",
];
const result = ASCII.reduce((accu, cur) => accu + String.fromCharCode(cur), "");
console.log(result); // I love jin
  • 求总价格
// 求总价格
const shopping = [
  {
    name: "球鞋",
    price: 200,
    num: 2,
  },
  {
    name: "球衣",
    price: 400,
    num: 1,
  },
  {
    name: "手套",
    price: 3,
    num: 6,
  },
  {
    name: "轮滑",
    price: 300,
    num: 10,
  },
];

const result = shopping.reduce((accu, cur) => accu + cur.price * cur.num, 0);
console.log(result); // 3818
  • 统计每个名字出现的次数: [‘Alice’,‘Bob’,‘Tiff’,‘Bruce’,‘Alice’]
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']

const result = names.reduce((accu, cur) => {
    accu[cur] = accu[cur] ? accu[cur] + 1 : 1
    return accu
}, {})
console.log(result)

在这里插入图片描述

  • 根据数据:[‘北京’,‘上海’,‘北京’,‘深圳’,‘杭州’,‘上海’,‘北京’] 得到数组:[[‘北京’,3],[‘上海’,2],[‘深圳’,],[‘杭州’,1]]
const citys = ["北京", "上海", "北京", "深圳", "杭州", "上海", "北京"];
const result = citys.reduce((accu, cur, index, arr) => {
  accu[cur] = ++accu[cur] || 1;
  // if(index === arr.length - 1){ // 迭代到了最后一次,返回整体结果
  //     // Object.entries() 将对象转换为二维数组
  //     return Object.entries(accu)
  // }else{ // 不是最后一次,返回accu累计的结果
  //     return accu
  // }

  // 简化版
  return index === arr.length - 1 ? Object.entries(accu) : accu;
}, {});
console.log(result);

在这里插入图片描述

手写一个 _reduce()

Array.prototype._reduce = function (callback, initiaValue) {
  // 1.判断数组有没有传入initiaValue
  const hasinitiaValue = typeof initiaValue !== "undefined";
  // 2.如果有从0开始,没有从1开始
  let i = hasinitiaValue ? 0 : 1;
  // 3.决定accu的初始值
  let accu = hasinitiaValue ? initiaValue : this[0];
  // 循环数组,起始下标根据有无 initiaValue 来决定
  for (; i < this.length; i++) {
    // 不断的迭代accu
    accu = callback(accu, this[i], i, this);
  }
  return accu;
};

const citys = ["北京", "上海", "北京", "深圳", "杭州", "上海", "北京"];
const result = citys._reduce((accu, cur, index, arr) => {
  accu[cur] = ++accu[cur] || 1;
  // if(index === arr.length - 1){ // 迭代到了最后一次,返回整体结果
  //     // Object.entries() 将对象转换为二维数组
  //     return Object.entries(accu)
  // }else{ // 不是最后一次,返回accu累计的结果
  //     return accu
  // }

  // 简化版
  return index === arr.length - 1 ? Object.entries(accu) : accu;
}, {});
console.log(result);

在这里插入图片描述

flat()

  • 作用:扁平化数组,把数组打平 —> 消除数组嵌套数组 —> 多维数组转一维数组

  • 返回:打平后的数组

  • 语法:array.flat(depth = 1)

    • 参数:扁平的深度,默认值是 1,只扁平一层
    • every:不管数组嵌套数组多少层,全部变成一维,depth 可以传 infinity(无穷)
  • 嵌套三层

const nums = [[123],[111,[456,[999]]],111,222,333]
const result = nums.flat(3)
console.log(result) // [123, 111, 456, 999, 111, 222, 333]
  • 嵌套多层
const nums = [[123],[[[[[[111,[456,[999]]]]]]]],111,222,333]
const result = nums.flat(Infinity)
console.log(result) // [123, 111, 456, 999, 111, 222, 333]
  • 手写一个 _flat()
// 实现flat方法的原理
Array.prototype._flat = function(depth = 1){
    return flatten(this, depth >= 1 ? depth : 1)
    function flatten(arr, depth){
        // 递归的结束标识,返回一个拷贝新的数组实例
        if(depth <= 0) return [...arr]
        return arr.reduce((accu, cur)=>{
            if(Array.isArray(cur)){ // cur是数组,递归处理
                accu.push(...flatten(cur,depth-1))
            }else{ // item不是数组,直接添加到accu中即可
                accu.push(cur)
            }
            return accu
        },[])
    }
}

const nums = [[123],[[[[[[111,[456,[999]]]]]]]],111,222,333]
const result = nums._flat(Infinity)
console.log(result) // [123, 111, 456, 999, 111, 222, 333]

const nums1 = [[111],[2222],333,444]
const result1 = nums1._flat(1)
console.log(result1) // [111, 2222, 333, 444]

相关资料

- Book Lists -