1.1 创建和初始化数组
有两种创建数组的方法:
- 关键字:
let arr = new Array()
- 字面量:
let arr = []
1.1.1 访问元素和迭代数组
求斐波那契数列的前为20个数字。
已知斐波那契数列中第一个数字是1,第二个是2,从第三项开始,每一项都等于前两项之和。
let fibonacci = [];
fibonacci[1] = 1;
fibonacci[2] = 2;
for (let i = 3; i < 20; i++) {
fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
}
for (let i = 1; i < fibonacci.length; i++) {
console.log(fibonacci[i]);
}
1.2 添加元素
// 假如有个数组 `numbers`,初始化成 0 到 9 :
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// 如果想给数组添加一个元素,可以这样做:
numbers[numbers.length] = 10;
1.2.1 使用 push 方法
使用 push
方法能添加任意个元素到数组的末尾:
numbers.push(11);
numbers.push(12, 13);
1.2.2 插入元素到数组首位
如果希望在数组首位插入元素:首先要腾出数组里第一个元素的位置,把所有的元素向右移动一位。
我们可以循环数组中的元素,从最后一位开始,将其对应的前一个元素的值赋值给它,依次处理,最后把我们想要添加的值赋给第一个位置。
for (let i = number.length; i >= 0; i--) {
numbers[i] = numbers[i-1];
}
numbers[0] = -1;
在 JavaScript 里,可以使用 unshift
方法将任意个元素插入数组的首位:
numbers.unshift(-2);
numbers.unshift(-4, -3);
1.3 删除元素
1.3.1 使用 pop 方法
使用 pop
方法可以删除数组里最后的元素:
numbers.pop();
通过
push
和pop
方法,就能用数组来模拟栈
1.3.2 从数组首位删除元素
可以循环数组中的元素,从第一位开始,让它后一个元素的值赋给它,依次处理。
for (let i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i+1];
}
这样做实质上是把数组里的元素都左移了一位,数组的长度依然未变,这意味着数组有额外的元素(值是undefined)。
要确实删除数组的第一个元素,可以使用 shift
方法:
numbers.shift();
通过
unshift
和shift
方法,就能用数组来模拟基本的队列数据结构
1.4 在任意位置添加或删除元素
可以使用 splice
方法,指定位置/索引,就可以删除相应位置和数量的元素:
// 删除从数组索引5开始的3个元素:numbers[5],numbers[6],numbers[7] 被删除了
numbers.splice(5, 3);
splice
方法还可以添加元素:
numbers.splice(5, 0, 2, 3, 4);
splice
方法接收的第一个参数,表示想要删除或插入的元素的索引值;第二个参数是删除元素的个数(在上面这个例子中,目的不是删除元素,所以传入0);第三个参数往后,就是要添加到数组里的值。
1.5 二维和多维数组
想要保存两天内每小时的平均气温,可以这样:
const averageTempDay1 = [72, 75, 79, 79, 81, 81];
const averageTempDay2 = [73, 76, 79, 74, 85, 81];
但这不是最好的办法,我们可以使用二维数组来存储这些信息:
let averageTemp = [];
averageTemp[0] = [72, 75, 79, 79, 81, 81];
averageTemp[1] = [73, 76, 79, 74, 85, 81];
1.5.1 迭代二元数组的元素
如果想看这个矩阵的输出,则可以创建一个通用函数:
const printMatrix = function(myMatrix) {
for (let i = 0; i < myMatrix.length; i++) {
for (let j = 0; j < myMatrix[i].length; j++) {
console.log(myMatrix[i][j]);
}
}
}
printMatrix(averageTemp);
1.5.2 多维数组
数据结构中有几个维度都没关系,我们可以用循环遍历每个维度来访问所有格子,例如 3×3×3 矩阵:
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
for (let z = 0; z < matrix[i][j].length; z++) {
console.log(matrix[i][j][z]);
}
}
}
1.6 数组方法参考
方法名 | 描述 |
---|---|
concat | 连接两个或更多数组,并返回结果 |
every | 对数组中的每一项运行给定函数,若该函数对每一项元素都返回true,则返回true |
filter | 对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组 |
forEach | 对数组中的每一项运行给定函数,没有返回值 |
join | 将所有数组元素连接成一个字符串 |
indexOf | 返回第一个与给定参数相等的数组元素的索引,没有则返回 -1 |
lastIndexOf | 返回在数组中搜索到的与给定参数相等的元素的索引里的最大的值 |
map | 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组 |
reverse | 颠倒数组中元素的顺序 |
slice | 传入索引值,将数组里对应索引范围内的元素作为新数组返回 |
some | 对数组中的每一项运行给定函数,如任一项返回true,则返回true |
sort | 按照字母顺序对数组排序,支持传入指定排序方法的函数作为参数 |
toString | 将数组作为字符串返回 |
valueOf | 和toString类似,将数组作为字符串返回 |
1.6.1 数组合并
concat
方法可以向一个数组传递数组、对象或是元素,数组会按传入参数的顺序连接指定数组。
const zero = 0;
const positiveNumbers = [1, 2, 3];
const negativeNumbers = [-3, -2, -1];
const numbers = negativeNumbers.concat(zero, positiveNumbers);
最后输出的结果是[-3, -2, -1, 0, 1, 2, 3]。
1.6.2 迭代器函数
有时需要迭代数组中的元素,可以用循环语句来处理,例如 for
语句。
JavaScript 内置了许多数组可用的迭代方法。
假如一个数组,它值是从 1 到 15 ,如果数组里的元素是偶数,函数就返回 true ,否则返回false:
const isEven = function(x) { console.log(x); return (x % 2) ? true : false; }; const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1. 用 every 方法迭代
every
方法会迭代数组中的每个元素,若该函数对每一项元素都返回true,则返回true:
numbers.every(isEven); // false
因为 numbers
第一个元素不是偶数,因此 isEven
函数返回 false ,然后 every
执行结束。
2. 用 some 方法迭代
对数组中的每一项运行给定函数,如任一项返回true,则返回true:
numbers.some(isEven); // true
第一个被迭代的元素是1,isEven
会返回 false;第二个被迭代的元素是 2 ,isEven
返回 true——迭代结束。
3. 用 forEach 方法迭代
如果要迭代整个数组,可以使用 forEach
方法,它和 for
循环结果相同:
numbers.forEach(function(x){
console.log((x % 2 == 0));
})
4. 使用 map 和 filter 方法
这两个方法会返回新数组。
第一个是 map
方法:对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
const myMap = numbers.map(isEven);
/*
[
false, true, false,
true, false, true,
false, true, false,
true, false, true,
false, true, false
]
*/
第二个是 filter
方法:返回该函数会返回true的项组成的数组
const myMap = numbers.filter(isEven);
/*
[
2, 4, 6, 8,
10, 12, 14
]
*/
5. 使用 reduce 方法
reduce
方法接收一个函数作为参数,这个函数有四个参数:previousValue
、currentValue
、index
和 array
。这个函数会返回一个将被叠加到累加器的值,reduce
方法停止执行后会返回这个累加器。如果要对一个数组中的所有元素求和,这就很有用:
numbers.reduce(function(previous, current, index) {
return previous + current;
});
1.6.3 排序元素
反序输出数组 numbers
(1,2,3,4,…,15):numbers.reverse()
。这时输出 [15,14,13,12,11,…,1]。
这时,使用 sort
方法:numbers.sort()
。输出会是:
[1,10,11,12,13,14,15,2,3,4,5,6,7,8,9]。
这是因为 sort
方法再对数组进行排序时,会默认把元素看出字符串进行比较。
// 可以传入自己写的比较函数
numbers.sort(function(a, b) {
return a - b;
});
// 函数也可以写成这样,更加清晰
function compare(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1
}
return 0;
}
numbers.sort(compare);
在 b 大于 a 时,会返回负数,反之会返回正数,如果相等的话,就返回 0 。
也就是说返回负数的话,就说明 a 比 b 小,这样 sort 可以根据返回值的情况给数组做升序排序。
1. 自定义排序
我们可以对任何类型的数组进行排序。例如,对象 Person
有名字和年龄属性,我们希望根据年龄排序,可以这样写:
let friends = [
{name: 'John', age: 30},
{name: 'Ana', age: 20},
{name: 'Chris', age: 25},
];
function comparePerson(a, b) {
return a.age - b.age;
}
console.log(friends.sort(comparePerson));
// 这将会按年龄升序排序
[
{ name: 'Ana', age: 20 },
{ name: 'Chris', age: 25 },
{ name: 'John', age: 30 }
]
2. 字符串排序
let friends = [
{name: 'John', age: 30},
{name: 'Ana', age: 20},
{name: 'Chris', age: 25},
];
function comparePerson(a, b) {
// 比较字符串时,不能这样简写
// return a.age - b.age;
// 若想忽略大小写,可以使用 toLowerCase() 或 toUpperCase()
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
console.log(friends.sort(comparePerson));
// 这将会按字母升序排序
[
{ name: 'Ana', age: 20 },
{ name: 'Chris', age: 25 },
{ name: 'John', age: 30 }
]
1.6.4 搜索
搜索有两个方法:indexOf
方法返回与参数匹配的第一个元素的索引,lastIndexOf
返回与参数匹配的最后一个元素的索引。若不存在,则均返回 -1
。
1. ES6—— find
和 findIndex
方法
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
function multipleOf13(element, index, array) {
return (element % 13 == 0) ? true : false;
};
console.log(numbers.find(multipleOf13));
console.log(numbers.findIndex(multipleOf13));
find
和 findIndex
方法接收一个回调函数,搜索一个满足回调函数条件的值。上面的例子中,要从数组中找到一个 13 的倍数。
find
返回第一个满足条件的值, findIndex
返回这个值的索引。如果没有满足条件的值,find
返回 undefined
,而 findIndex
返回 -1。
2. ES7—— includes
方法
如果数组存在某个元素,includes
会返回 true
,否则返回 false
。
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
console.log(numbers.includes(15));
console.log(numbers.includes(20));
可以给 includes
方法传入一个起始索引,搜索会从索引指定的位置开始:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
console.log(numbers.includes(2, 2));
输出 false
,因为从索引 2 之后的元素不包含 2。
1.6.5 输出数组为字符串
如果想把数组里的所有元素输出为一个字符串,可以用 toString
方法:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
console.log(numbers.toString()); // => 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
如果想用不同的分隔符把元素隔开,可以使用 join
方法:
console.log(numbers.join('-')); // => 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
];
console.log(numbers.includes(2, 2));
输出 `false` ,因为从索引 2 之后的元素不包含 2。
### 1.6.5 输出数组为字符串
如果想把数组里的所有元素输出为一个字符串,可以用 `toString` 方法:
```js
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
console.log(numbers.toString()); // => 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
如果想用不同的分隔符把元素隔开,可以使用 join
方法:
console.log(numbers.join('-')); // => 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15