返回

JS 数组之洞天福地:深入探索 Array

前端

引言

JavaScript 数组,一个看似简单的数据结构,却蕴含着深厚的洞天福地。从判断数组的方法到去重、扁平化的技巧,每一块领域都值得我们细细探究。踏入这片数组的奇幻之旅,让我们深入挖掘它的奥秘,解锁数据处理的新境界。

一、数组判断方法大荟萃

要操纵数组,首先要学会辨识其真伪。JavaScript 提供了一系列强大的判断方法,助你轻松掌握数组的本质:

Array.isArray(obj)

断定一个对象是否为数组类型。

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false

obj instanceof Array

同上,使用 instanceof 运算符进行判断。

console.log([] instanceof Array); // true
console.log({} instanceof Array); // false

obj.constructor === Array

考察对象的构造函数是否为 Array。

console.log([] constructor === Array); // true
console.log({} constructor === Array); // false

Object.prototype.toString.call(obj) === '[object Array]'

通过 toString 方法探查对象的类型。

console.log(Object.prototype.toString.call([]) === '[object Array]'); // true
console.log(Object.prototype.toString.call({}) === '[object Array]'); // false

Array.from(obj) !== obj

如果从 obj 转换出的数组不等于 obj 本身,则 obj 很有可能不是数组。

console.log(Array.from([]) !== []); // true
console.log(Array.from({}) !== {}); // true

二、数组常用方法,游刃有余

驾驭数组,常用方法必不可少。掌握以下利器,让你的数据处理事半功倍:

Array.prototype.forEach(callback)

遍历数组的每一个元素,执行指定的回调函数。

const arr = [1, 2, 3];
arr.forEach((item) => {
  console.log(item);
});

Array.prototype.map(callback)

返回一个新数组,其中包含了回调函数在每个元素上执行后的结果。

const arr = [1, 2, 3];
const newArr = arr.map((item) => item * 2);
console.log(newArr); // [2, 4, 6]

Array.prototype.filter(callback)

返回一个新数组,其中包含了回调函数为 true 的元素。

const arr = [1, 2, 3, 4];
const newArr = arr.filter((item) => item % 2 === 0);
console.log(newArr); // [2, 4]

Array.prototype.reduce(callback)

将数组元素逐步累积,返回一个最终值。

const arr = [1, 2, 3, 4];
const sum = arr.reduce((accumulator, item) => accumulator + item, 0);
console.log(sum); // 10

Array.prototype.find(callback)

找到数组中第一个满足回调函数为 true 的元素。

const arr = [1, 2, 3, 4];
const found = arr.find((item) => item > 2);
console.log(found); // 3

Array.prototype.findIndex(callback)

返回数组中第一个满足回调函数为 true 的元素的索引。

const arr = [1, 2, 3, 4];
const index = arr.findIndex((item) => item > 2);
console.log(index); // 2

三、数组去重,精益求精

去除数组中的重复元素,是数据处理中常见需求。掌握以下技巧,让你的数组更加精简:

Set 数据结构

利用 Set 的自动去重特性,将数组元素转化为 Set,再将其转化回数组。

const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]

indexOf 和 filter

通过 indexOf 查找重复元素,并使用 filter 过滤出不重复的元素。

const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

includes

借助 includes 方法逐个检查元素,发现重复后删除。

const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item) => !arr.includes(item));
console.log(uniqueArr); // [1, 2, 3, 4, 5]

哈希表

创建一个哈希表,用元素作为键,布尔值作为值。如果一个元素已被哈希表记录,则跳过。

const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [];
const hashTable = {};

arr.forEach((item) => {
  if (!hashTable[item]) {
    uniqueArr.push(item);
    hashTable[item] = true;
  }
});
console.log(uniqueArr); // [1, 2, 3, 4, 5]

四、数组扁平化,化繁为简

将多维数组转换为一维数组的过程称为扁平化。以下方法让你轻松搞定:

Array.prototype.flat(depth)

指定扁平化的深度,将其转换成一维数组。

const arr = [[1, 2], [3, [4, 5]]];
const flatArr = arr.flat(2);
console.log(flatArr); // [1, 2, 3, 4, 5]

for 循环

使用嵌套 for 循环逐个遍历数组元素,将多维数组还原为一维数组。

const arr = [[1, 2], [3, [4, 5]]];
const flatArr = [];

for (let i = 0; i < arr.length; i++) {
  if (Array.isArray(arr[i])) {
    flatArr.push(...flatArr);
    flatArr.push(...arr[i]);
  } else {
    flatArr.push(arr[i]);
  }
}
console.log(flatArr); // [1, 2, 3, 4, 5]

递归

通过递归函数,将多维数组不断拆解,直至达到一维状态。

const arr = [[1, 2], [3, [4, 5]]];
function flattenArray(arr) {
  return arr.reduce((acc, item) => {
    return acc.concat(Array.isArray(item) ? flattenArray(item) : item);
  }, []);
}

const flatArr = flattenArray(arr);
console.log(flatArr); // [1, 2, 3, 4, 5]

concat 和 reduce

使用 concat 方法连接子数组,并通过 reduce 扁平化嵌套数组。

const arr = [[1, 2], [3, [4, 5]]];
const flatArr = [].concat(...arr).reduce((acc, item) => {
  return acc.concat(Array.isArray(item) ? flattenArray(item) : item);
}, []);
console.log(flatArr); // [1, 2, 3, 4, 5]

五、结语

JS 数组之洞天福地,博大精深,涵盖广泛。从判断数组的方法到去重、扁平化的技巧,掌握这些知识将为你打开数据处理的新大门。探索这片奇幻之旅,用智慧解锁数组的奥秘,提升你的编程技能,让代码世界大放异彩。