在 JavaScript 中,Array类有许多强大的内置方法可用于转换数组。
相比使用简单的for循环或更直接的操作,这些方法让把一个数组转换成另一个数组容易得多。
有些方法是纯的,这意味着它们不会修改原始数组。 它们会返回一个新数组。 不过,其他方法会操作调用它们的数组,并且不会返回修改后的数组。
下面介绍一些最常用的数组转换方法。 完整的方法列表可以在 MDN 文档 中找到。
通过一个作为实参传入的函数来转换每个元素,从而创建一个新数组。 这些回调函数通常写成箭头函数。
let arr = [1, 2, 3, 4];
const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]
值得注意的是,结果数组的长度总是与原数组相同。
用一个过滤函数(如果元素应保留则返回 true,如果应移除则返回 false)来过滤当前数组,从而创建一个新数组。
let arr = [1, 2, 3, 4];
arr.filter((value) => value % 2 === 0);
// => [2, 4]
使用一个函数将数组归约为单个值,该函数以_累加器_和数组的当前元素作为形参。 该函数说明如何将当前元素合并到累加器中,并返回将在下一次迭代中使用的累加器。
let arr = [1, 2, 3, 4];
// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10
// Classify the numbers by whether they are odd or not
arr.reduce(
(accumulator, currentValue) => {
if (currentValue % 2 === 0) {
accumulator.even.push(currentValue);
} else {
accumulator.odd.push(currentValue);
}
return accumulator;
},
{ even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }
反转数组的元素。
const arr = [1, 2, 3, 4];
arr.reverse();
// => [4, 3, 2, 1]
该方法会修改调用它的数组。
给定起始下标和结束下标,从传入的数组创建一个子数组。
结束下标处的元素不会被包含在内。
此外,所有形参都是可选的:
起始下标默认为0,结束下标默认为数组长度。
const arr = [1, 2, 3, 4];
arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]
移除、替换和/或添加数组中的新元素。
它接受以下形参:
splice返回已移除的元素。
const arr = ['1', '2', '5', '6'];
// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']
// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']
// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']
默认情况下,sort会先将数组元素转换为字符串,然后应用字符串比较来对数组排序(参见概念:比较)。
排序是_原地_进行的,这意味着原始数组会被修改。
sort还会返回修改后的数组,如果你想在其后链式调用其他方法,这会很方便。
const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']
要自定义排序行为,可以传入一个比较函数作为实参。 比较函数本身会以两个实参调用,这两个实参是数组的两个元素。 然后它需要返回以下内容:
0
下面是一个示例,展示如何使用自定义比较函数来排序对象数组。
const arr = [
{ name: 'Lydia', age: 7 },
{ name: 'Anne', age: 34 },
{ name: 'Holger', age: 59 },
];
arr.sort((item1, item2) => {
if (item1.name < item2.name) {
return -1;
}
if (item1.name > item2.name) {
return 1;
}
return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]
Elyse 是一位见习魔术师,她还在继续自己的训练。别人会给她一副牌,她要试着把这副牌变个样:让某些牌出现、消失、改变数字,或者彻底重新排列。 为了简单起见,她通常只用编号 1 到 10 的牌开始,不过有些魔术可能会变出数字更大的牌。
Elyse 想把牌堆里每张牌的数字翻倍。这样变出来的牌可能比 1 到 10 更大。
const deck = [1, 2, 3, 4, 10];
seeingDouble(deck);
// => [2, 4, 6, 8, 20]
Elyse 想把牌堆里出现的每个 3 都变成三张。如果一副牌里原本只有一张 3,变完魔术后,原来的那张 3 就会变成三张 3。
const deck = [1, 3, 9, 3, 7];
threeOfEachThree(deck);
// => [1, 3, 3, 3, 9, 3, 3, 3, 7]
Elyse 会拿一副 10 张的牌,让除了中间两张以外的所有牌都消失。
const deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
middleTwo(deck);
// => [5, 6]
Elyse 想把牌堆最上面和最下面的两张牌移到中间,并且颠倒它们的顺序。
你可以假设牌堆里的牌数是偶数。
const deck = [1, 2, 3, 5, 6, 10];
sandwichTrick(deck);
// => [2, 3, 10, 1, 5, 6]
Elyse 今天最喜欢的数字是 2。在这个魔术里,牌堆中所有不是 2 的牌都会消失。
const deck = [1, 2, 3, 4, 10, 2];
twoIsSpecial(deck);
// => [2, 2]
Elyse 想展示自己完美重排这些牌的本领,不管它们被洗得多乱。
const deck = [10, 1, 5, 3, 2, 8, 7];
perfectlyOrdered(deck);
// => [1, 2, 3, 5, 7, 8, 10]
Elyse 想改变牌堆里牌的顺序。 变完魔术后,现在最上面的那张牌应该跑到牌堆最下面。第二张牌应该跑到倒数第二张的位置,以此类推。
const deck = [10, 1, 5, 3, 2];
reorder(deck);
// => [2, 3, 5, 1, 10]