数组的各种方法此篇足够

157 阅读14分钟

与数组(Array)的Love and hate

老样子,来一句励志诗句洗洗脑先!

不经一番寒彻骨,怎得梅花扑鼻香。

* 看完这篇文章你可以学到什么

1、什么是数组
2、快速生成数组的方法
3、数组的方法
  • Array.at()
  • Array.concat()
  • Array.copyWithin()
  • Array.entries()
  • Array.every()
  • Array.fill()
  • Array.filter()
  • Array.find()
  • Array.findIndex()
  • Array.findLast()
  • Array.findLastIndex()
  • Array.flat()
  • Array.flatMap()
  • Array.forEach()
  • Array.group()
  • Array.groupToMap()
  • Array.includes()
  • Array.indexOf()
  • Array.join()
  • Array.keys()
  • Array.lastIndexOf()
  • Array.map()
  • Array.pop()
  • Array.push()
  • Array.reduce()
  • Array.reduceRight()
  • Array.reverse()
  • Array.shift()
  • Array.slice()
  • Array.some()
  • Array.sort()
  • Array.splice()
  • Array.toLocaleString()
  • Array.toReversed()
  • Array.toSorted()
  • Array.toSpliced()
  • Array.toString()
  • Array.unshift()
  • Array.values()
  • Array.with()
  • Array.[@@iterator]()

一、初识数组

数组的自我介绍

数组(array)是一种最简单的复合数据类型,它是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和不同的下标来确定数组中唯一的元素。根据数组的维度,可以将其分为一维数组、二维数组和多维数组等。

用白话来讲就是:数组通常被描述为“像列表一样的对象”,它是一个包含了多个值的对象。数组对象可以存储在变量中,并且能用和其他任何类型的值完全相同的方式处理,区别在于我们可以单独访问列表中的每个值,并使用列表执行一些有用和高效的操作,如循环 - 它对数组中的每个元素都执行相同的操作。如果我们没有数组,我们必须将每个产品存储在一个单独的变量中,然后调用打印的代码,并为每个产品单独添加。花费的时间要长得多,效率很低,而且也容易出错。

数组的描述

在 JavaScript 中,数组不是基本类型,而是具有以下核心特征的 Array 对象:

  • JavaScript 数组是可调整大小的,并且可以包含不同的数据类型。(当不需要这些特征时,可以使用类型化数组。)
  • JavaScript 数组不是关联数组,因此,不能使用任意字符串作为索引访问数组元素,但必须使用非负整数(或它们各自的字符串形式)作为索引访问。
  • JavaScript 数组的索引从 0 开始:数组的第一个元素在索引 0 处,第二个在索引 1 处,以此类推,最后一个元素是数组的 length 属性减去 1 的值。
  • JavaScript 数组复制操作创建浅拷贝。(所有 JavaScript 对象的标准内置复制操作都会创建浅拷贝,而不是深拷贝)。

二、快速生成数组的方法

我们可以通过Array.from()方法从一个类似数组或可迭代对象中创建一个新的,浅拷贝的数组实例。

var arr = Array.from(Array(length), (v,k) =>k);
console.log(arr);

01.png

三、数组的方法

Array.at()

at()  方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。

const array = [5, 12, 8, 130, 44]

let index = 2;
console.log(array.at(index));   
// Expected output: number 8

index = -2
console.log(array.at(index));   
// Expected output: number 130
Array.concat()

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

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);    
// Expected output: Array ["a", "b", "c", "d", "e", "f"]
Array.copyWithin()

copyWithin()  方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。

const array = ['a', 'b', 'c', 'd', 'e'];

// 将索引3处的元素复制到索引0
console.log(array.copyWithin(0, 3, 4));
// Expected output: Array ["d", "b", "c", "d", "e"]

// 将从索引3到末尾的所有元素复制到索引1
console.log(array.copyWithin(1, 3));
// Expected output: Array ["d", "d", "e", "d", "e"]
Array.entries()

entries()  方法返回一个新的数组迭代器 (en-US)对象,该对象包含数组中每个索引的键/值对。

const array = ['a', 'b', 'c'];

const iterator = array.entries();

console.log(iterator.next().value);
// Expected output: Array [0, "a"]

console.log(iterator.next().value);
// Expected output: Array [1, "b"]
Array.every()

every()  方法测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。

const isBelowThreshold = (currentValue) => currentValue < 40;

const array = [1, 30, 39, 29, 10, 13];

console.log(array.every(isBelowThreshold));
// Expected output: true
Array.fill()

fill()  方法用一个固定值填充一个数组中从起始索引(默认为 0)到终止索引(默认为 array.length)内的全部元素。它返回修改后的数组。

const array = [1, 2, 3, 4];

// 从位置2到位置4填充0
console.log(array.fill(0, 2, 4));
// Expected output: Array [1, 2, 0, 0]

// 从位置1开始填充5
console.log(array.fill(5, 1));
// Expected output: Array [1, 5, 5, 5]

console.log(array.fill(6));
// Expected output: Array [6, 6, 6, 6]
Array.filter()

filter()  方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]

Array.find()

find()  方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

  • 如果需要在数组中找到对应元素的索引,请使用 findIndex()
  • 如果需要查找某个值的索引,请使用 Array.indexOf()。(它类似于 findIndex(),但只是检查每个元素是否与值相等,而不是使用测试函数。)
  • 如果需要查找数组中是否存在某个值,请使用 Array.includes()。同样,它检查每个元素是否与值相等,而不是使用测试函数。
  • 如果需要查找是否有元素满足所提供的测试函数,请使用 Array.some()
const array = [5, 12, 8, 130, 44];

const found = array.find(element => element > 10);

console.log(found);
// Expected output: 12
Array.findIndex()

findIndex()  方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1。

另请参阅 find() 方法,它返回满足测试函数的第一个元素(而不是它的索引)。

const array = [5, 12, 8, 130, 44];

const isLargeNumber = (element) => element > 13;

console.log(array.findIndex(isLargeNumber));
// Expected output: 3
Array.findLast()

findLast()  方法反向迭代数组,并返回满足提供的测试函数的第一个元素的值。如果没有找到对应元素,则返回 undefined

如果你需要找到:

  • 第一个匹配的元素,使用 find()
  • 数组中最后一个匹配元素的索引,使用 findLastIndex()
  • 某个值的索引,使用 indexOf()。(它类似于 findIndex(),但是会检查每个元素是否与值相等,而不是使用一个测试函数。)
  • 该数组中是否存在一个值,使用 includes()。同样地,它检查每个元素是否和值相等,而不是使用一个测试函数。
  • 是否有任意一个元素满足提供的测试函数,使用 some()
const array = [5, 12, 50, 130, 44];

const found = array.findLast((element) => element > 45);

console.log(found);
// Expected output: 130
Array.findLastIndex()

findLastIndex()  方法反向迭代数组,并返回满足所提供的测试函数的第一个元素的索引。若没有找到对应元素,则返回 -1。

另请参见 findLast() 方法,该方法返回最后一个满足测试函数的元素的值(而不是它的索引)。

const array = [5, 12, 50, 130, 44];

const isLargeNumber = (element) => element > 45;

console.log(array.findLastIndex(isLargeNumber));
// Expected output: 3
// 有值元素的索引: 130
Array.flat()

flat()  方法创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。

const array = [0, 1, 2, [3, 4]];

console.log(array.flat());
// Expected output: Array [0, 1, 2, 3, 4]

const arr2 = [0, 1, 2, [[[3, 4]]]];

console.log(arr2.flat(2));
// Expected output: Array [0, 1, 2, Array [3, 4]]

Array.flatMap()

flatMap()  方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。它等价于在调用 map() 方法后再调用深度为 1 的 flat() 方法(arr.map(...args).flat()),但比分别调用这两个方法稍微更高效一些。

const arr1 = [1, 2, 1];

const result = arr1.flatMap((num) => (num === 2 ? [2, 2] : 1));

console.log(result);
// Expected output: Array [1, 2, 2, 1]
Array.forEach()

forEach()  方法对数组的每个元素执行一次给定的函数。

const array = ['a', 'b', 'c'];

array.forEach(element => console.log(element));

// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
Array.group()

group()  方法根据提供的测试函数返回的字符串值,将调用数组的元素分组。返回的对象具有每个组的单独属性,其中包含组中的元素数组。

当分组名称可以用字符串表示时,应使用此方法。如果你需要使用某个任意值作为键来分组元素,请改用 Array.groupToMap() 方法。

点击此处查看详情

Array.groupToMap()

groupToMap()  方法根据提供的测试函数返回的值对调用数组的元素进行分组。最终返回的 Map 使用测试函数返回的唯一值作为键,可以用于获取每个组中的元素数组。

该方法主要用于分组与对象相关的元素,特别是当该对象可能随时间而变化时。如果对象不变,你可以使用字符串表示它,并使用 Array.group() 分组元素。

点击此处查看详情

Array.includes()

includes()  方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false

const array = [1, 2, 3];

console.log(array.includes(2));
// Expected output: true

const pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// Expected output: true

console.log(pets.includes('at'));
// Expected output: false
Array.indexOf()

indexOf()  方法返回数组中第一次出现给定元素的下标,如果不存在则返回 -1。

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];

console.log(beasts.indexOf('bison'));
// Expected output: 1

// Start from index 2
console.log(beasts.indexOf('bison', 2));
// Expected output: 4

console.log(beasts.indexOf('giraffe'));
// Expected output: -1
Array.join()

join()  方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一个元素,那么将返回该元素而不使用分隔符。

const elements = ['Fire', 'Air', 'Water'];

console.log(elements.join());
// Expected output: "Fire,Air,Water"

console.log(elements.join(''));
// Expected output: "FireAirWater"

console.log(elements.join('-'));
// Expected output: "Fire-Air-Water"
Array.keys()

keys()  方法返回一个新的数组迭代器 (en-US)对象,其中包含数组中每个索引的键。

const array = ['a', 'b', 'c'];
const iterator = array.keys();

for (const key of iterator) {
  console.log(key);
}

// Expected output: 0
// Expected output: 1
// Expected output: 2
Array.lastIndexOf()

lastIndexOf()  方法返回数组中给定元素最后一次出现的索引,如果不存在则返回 -1。该方法从 fromIndex 开始向前搜索数组。

const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];

console.log(animals.lastIndexOf('Dodo'));
// Expected output: 3

console.log(animals.lastIndexOf('Tiger'));
// Expected output: 1
Array.map()

map()  方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

const array = [1, 4, 9, 16];

// Pass a function to map
const map1 = array.map(x => x * 2);

console.log(map1);
// Expected output: Array [2, 8, 18, 32]
Array.pop()

pop()  方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。

const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];

console.log(plants.pop());
// Expected output: "tomato"

console.log(plants);
// Expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"]

plants.pop();

console.log(plants);
// Expected output: Array ["broccoli", "cauliflower", "cabbage"]
Array.push()

push()  方法将指定的元素添加到数组的末尾,并返回新的数组长度。

const animals = ['pigs', 'goats', 'sheep'];

const count = animals.push('cows');
console.log(count);
// Expected output: 4
console.log(animals);
// Expected output: Array ["pigs", "goats", "sheep", "cows"]

animals.push('chickens', 'cats', 'dogs');
console.log(animals);
// Expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]
Array.reduce()

reduce()  方法对数组中的每个元素按序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被用作初始值,迭代器将从第二个元素开始执行(即从索引为 1 而不是 0 的位置开始)。

const array = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  initialValue
);

console.log(sumWithInitial);
// Expected output: 10
Array.reduceRight()

reduceRight()  方法对累加器(accumulator)和数组的每个值(按从右到左的顺序)应用一个函数,并使其成为单个值。

对于从左至右遍历的相似方法,请参阅 Array.reduce()

const array = [[0, 1], [2, 3], [4, 5]];

const result = array.reduceRight((accumulator, currentValue) => accumulator.concat(currentValue));

console.log(result);
// Expected output: Array [4, 5, 2, 3, 0, 1]
Array.reverse()

reverse()  方法就地反转数组中的元素,并返回同一数组的引用。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。换句话说,数组中的元素顺序将被翻转,变为与之前相反的方向。

要在不改变原始数组的情况下反转数组中的元素,使用 toReversed()

const array = ['one', 'two', 'three'];
console.log('array:', array);
// Expected output: "array:" Array ["one", "two", "three"]

const reversed = array.reverse();
console.log('reversed:', reversed);
// Expected output: "reversed:" Array ["three", "two", "one"]

// Careful: reverse is destructive -- it changes the original array.
console.log('array:', array);
// Expected output: "array:" Array ["three", "two", "one"]
Array.shift()

shift()  方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

const array = [1, 2, 3];

const firstElement = array.shift();

console.log(array);
// Expected output: Array [2, 3]

console.log(firstElement);
// Expected output: 1
Array.slice()

slice()  方法返回一个新的数组对象,这一对象是一个由 start 和 end 决定的原数组的浅拷贝(包括 start,不包括 end),其中 start 和 end 代表了数组元素的索引。原始数组不会被改变。

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]

console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]

console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]
Array.some()

some()  方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false。它不会修改数组。

const array = [1, 2, 3, 4, 5];

// Checks whether an element is even
const even = (element) => element % 2 === 0;

console.log(array.some(even));
// Expected output: true

Array.sort()

sort()  方法就地对数组的元素进行排序,并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。

由于它取决于具体实现,因此无法保证排序的时间和空间复杂度。

如果想要不改变原数组的排序方法,可以使用 toSorted()

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// Expected output: Array ["Dec", "Feb", "Jan", "March"]

const array = [1, 30, 4, 21, 100000];
array.sort();
console.log(array);
// Expected output: Array [1, 100000, 21, 30, 4]
Array.splice()

splice()  方法通过移除或者替换已存在的元素和/或添加新元素就地改变一个数组的内容。

要创建一个删除和/或替换部分内容而不改变原数组的新数组,请使用 toSpliced()。要访问数组的一部分而不修改它,参见 slice()

const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// 插入索引1
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]

months.splice(4, 1, 'May');
// 替换索引4处的1个元素
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "May"]
Array.toLocaleString()

toLocaleString()  方法返回一个字符串,表示数组中的所有元素。每个元素通过调用它们自己的 toLocaleString 方法转换为字符串,并且使用特定于语言环境的字符串(例如逗号“,”)分隔开。

const array = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
const localeString = array.toLocaleString('en', { timeZone: 'UTC' });

console.log(localeString);
// Expected output: "1,a,12/21/1997, 2:12:00 PM",
// 这假设了“en”区域设置和UTC时区-您的结果可能会有所不同
Array.toReversed()

Array 实例的 toReversed()  方法是 reverse() 方法对应的复制版本。它返回一个元素顺序相反的新数组。点击此处查看详情

Array.toSorted()

Array 实例的 toSorted()  方法是 sort() 方法的复制方法版本。它返回一个新数组,其元素按升序排列。点击此处查看详情

Array.toSpliced()

Array 实例的 toSpliced()  方法是 splice() 方法的复制版本。它返回一个新数组,并在给定的索引处删除和/或替换了一些元素。点击此处查看详情

Array.toString()

toString()  方法返回一个字符串,表示指定的数组及其元素。

const array = [1, 2, 'a', '1a'];

console.log(array.toString());
// Expected output: "1,2,a,1a"
Array.unshift()

unshift()  方法将指定元素添加到数组的开头,并返回数组的新长度。

const array = [1, 2, 3];

console.log(array.unshift(4, 5));
// Expected output: 5

console.log(array);
// Expected output: Array [4, 5, 1, 2, 3]
Array.values()

values()  方法返回一个新的数组迭代器 (en-US)对象,该对象迭代数组中每个元素的值。

const array = ['a', 'b', 'c'];
const iterator = array.values();

for (const value of iterator) {
  console.log(value);
}

// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
Array.with()

Array 实例的 with()  方法是使用方括号表示法修改指定索引值的复制方法版本。它会返回一个新数组,其指定索引处的值会被新值替换。点击此处查看详情

Array.[@@iterator]()

Array 实例的  [@@iterator]()  方法实现了迭代协议,允许数组被大多数期望可迭代对象的语法所使用,例如展开语法和 for...of 循环。它返回一个数组迭代器对象 (en-US),该对象会产生数组中每个索引的值。

该属性的初始值与 Array.values 属性的初始值是相同的函数对象。点击此处查看详情

结束

“希君生羽翼,一化北溟鱼。”