创建和初始化数组

数组是最简单的内存数据结构。

Q:为什么用数组?

A:

使用 new 关键字创建和初始化数组(不推荐)

  1. 使用 new 关键字声明并初始化
  2. 可以创建一个指定长度的数组
  3. 可以直接将数组元素作为参数传递给它的构造器
  1. let week = new Array();
  2. week = new Array(7);
  3. week = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');

使用 [] 的形式创建和初始化数组(推荐)

  1. let week = [];
  2. // or
  3. week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  • 使用数组的 length 属性输出数组存了多少个元素(它的大小)
  1. console.log(week.length); // 7
  • 访问元素和迭代数组
  1. for (let i = 0; i < week.length; i++) {
  2. console.log(week[i]);
  3. }
  4. // 输出每个元素后都是换行的,这里用两个空格代表,你懂的
  5. // Sunday Monday Tuesday Wednesday Thursday Friday Saturday

Example:斐波那契数列

斐波那契数列中的前两项是 1,从第三项开始,每一项都等于前两项之和。

  1. // 求斐波那契数列的前 20 个数
  2. let a = 20;
  3. const fibonacci = [];
  4. fibonacci[1] = 1;
  5. fibonacci[2] = 1;
  6. for(let i = 3; i < a; i++) {
  7. fibonacci[i] = fibonacci[i -1] + fibonacci[i -2];
  8. }
  9. for(let i = 1; i < fibonacci.length; i++) {
  10. console.log(fibonacci[i]);
  11. }
  12. // 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

添加元素

  1. let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

在数组末尾插入元素

  • 把值赋给数组中最后一个空位上的元素
  1. numbers[numbers.length] = 10;
  • push() 方法(在数组的末尾添加元素)
  1. numbers.push(11);
  2. numbers.push(12, 13);
  3. console.log(numbers); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]

在数组开头插入元素

  • (原生)在数组开头插入元素
  1. Array.prototype.insertFirstPosition = function (value) {
  2. for (let i = this.length; i >= 0; i--) {
  3. this[i] = this[i - 1];
  4. }
  5. this[0] = value;
  6. }
  7. numbers.insertFirstPosition(-1); // [ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
  • unshift()(在数组的开头添加元素)
  1. numbers.unshift(-2);
  2. numbers.unshift(-4, -3);
  3. console.log(numbers); // [ -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]

删除元素

在数组末尾删除元素

  • pop()(从数组末尾删除元素)
  1. numbers.pop();
  2. console.log(numbers); // [ -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]

在数组开头删除元素

  • (原生)从数组开头删除元素(不推荐)
  1. // 步骤一:将所有不是 undefined 的值从原来的数组复制到新的数组中,创建一个 reIndex 方法
  2. Array.prototype.reIndex = function(myArray) {
  3. const newArray = [];
  4. for (let i = 0; i < myArray.length; i++) {
  5. if (myArray[i] !== undefined) {
  6. newArray.push(myArray[i]);
  7. }
  8. }
  9. return newArray;
  10. }
  11. // 步骤二:手动移除第一个元素并重新排序
  12. Array.prototype.removeFirst = function() {
  13. for (let i = 0; i < this.length; i++) {
  14. this[i] = this[i + 1];
  15. }
  16. return this.reIndex(this);
  17. };
  18. // 步骤三:调用函数删除
  19. numbers.removeFirst();
  20. console.log(numbers); // [ -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, undefined ]

从中可以得出,只是用后一个值覆盖了前一个值,数组长度并未改变。

  • shift() (删除数组的第一个元素)

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

  1. numbers.shift(); // -3
  2. console.log(numbers); // [ -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, undefined ]

在数组任意位置添加或删除元素 splice()

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

参数:

  1. 第一个:表示想要删除或插入的元素的索引值
  2. 第二个:表示想要删除元素的个数
  3. 第三个往后:表示想要添加到数组里的值
  1. // 删除从数组索引 5 开始的 3 个元素
  2. numbers.splice(5, 3); // [ 3, 4, 5 ]
  3. // 从索引 5 开始添加元素 2、3、4
  4. numbers.splice(5, 0, 2, 3, 4); // []
  5. console.log(numbers); // [-2, -1, 0, 1, 2, 2, 3, 4, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, undefined]

二维和多维数组

Q:为什么用二维数组(矩阵)?

A:

  • 二维数组
    迭代所有的行和列,使用一个嵌套的 for 循环来处理,其中变量 i 为行,变量 j 为列。在这种情况下,每个 myMatrix[i] 同样代表一个数组,因此需要在嵌套的 for 循环中迭代 myMatrix[i] 的每个位置。
  1. // 二维数组
  2. let matrix = [];
  3. matrix[0] = [72, 75, 79, 79, 81, 81];
  4. matrix[1] = [81, 79, 75, 75, 73, 73];
  5. // 迭代二维数组的元素
  6. function printMatrix(myMatrix) {
  7. for (let i = 0; i < myMatrix.length; i++) {
  8. for (let j = 0; j < myMatrix[i].length; j++) {
  9. console.log(myMatrix[i][j]);
  10. }
  11. }
  12. }
  13. printMatrix(matrix);
  14. // 输出每个元素后都是换行的,这里用两个空格代表,你懂的(下面的也是这样)
  15. // 72 75 79 79 81 81
  16. // 81 79 75 75 73 73
  • 多维数组
  1. // 多维数组(例如:创建一个 3*3*3 的矩阵,每一个格子里包含矩阵的 i(行)、j(列)、z(深度) 之和)
  2. const matrix3 = [];
  3. for (let i = 0; i < 3; i++) {
  4. matrix3[i] = []; // 初始化每个数组
  5. for (let j = 0; j < 3; j++) {
  6. matrix3[i][j] = [];
  7. for (let z = 0; z < 3; z++) {
  8. matrix3[i][j][z] = i + j + z;
  9. }
  10. }
  11. }
  12. // 迭代多维数组
  13. for (let i = 0; i < matrix3.length; i++) {
  14. for (let j = 0; j < matrix3[i].length; j++) {
  15. for (let z = 0; z < matrix3[i][j].length; z++) {
  16. console.log(matrix3[i][j][z]);
  17. }
  18. }
  19. }
  20. // 0 1 2 1 2 3 2 3 4
  21. // 1 2 3 2 3 4 3 4 5
  22. // 2 3 4 3 4 5 4 5 6

数组合并 concat()

  • concat() 连接 2 个或 2 个已上的数组,并返回结果。
  • concat() 可以向一个数组传递数组、对象或是元素。数组会按照该方法传入的参数顺序连接指定的数组。
  1. const zero = 0;
  2. const positiveNumbers = [1, 2, 3];
  3. const negativeNumbers = [-3, -2, -1];
  4. let numbers = negativeNumbers.concat(zero, positiveNumbers); // [-3, -2, -1, 0, 1, 2, 3]

迭代数组元素

我们需要一个数组和一个函数:如果数组里的元素可以被 2 整除(偶数),函数就返回 true,否则返回 false。

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
  2. const isEven = x => x % 2 === 0;
  3. /* 另一种实现方式
  4. function isEven(x) {
  5. // return x % 2 === 0 ? true : false;
  6. return (x % 2 === 0);
  7. }
  8. */

迭代器 every()

every() 方法迭代(every() 方法会迭代数组中的每一个元素,直到返回 false

  1. const myEvery = numbers.every(isEven);
  2. console.log(myEvery); // false

迭代器 some()

some() 方法迭代(some() 方法会迭代数组中的每一个元素,直到返回 true

  1. const mySome = numbers.some(isEven);
  2. console.log(mySome); // true

迭代器 forEach()

forEach() 方法迭代(forEach() 方法会迭代数组中的每一个元素,它和使用 for 循环的结构相同)

  1. numbers.forEach(x => console.log(x % 2 === 0));
  2. // false true false true false true false true false true false true false true false

迭代器 map()

map() 方法迭代(map() 方法会返回新数组)

  1. const myMap = numbers.map(isEven);
  2. console.log(myMap); // [ false, true, false, true, false, true, false, true, false, true, false, true, false, true, false]

迭代器 filter()

filter() 方法迭代(filter() 方法返回的新数组由 isEven() 函数返回 true 的元素)

  1. const myFilter = numbers.filter(isEven);
  2. console.log(myFilter); // [ 2, 4, 6, 8, 10, 12, 14 ]

迭代器 reduce()

reduce() 方法迭代 (reduce() 方法会返回一个将被叠加到累加器的值,reduce() 方法停止执行后会返回这个累加器)

  1. const myReduce = numbers.reduce((previousValue, currentValue) => previousValue + currentValue);
  2. console.log(myReduce); // 120

迭代器 entries()

使用 entries() 迭代(返回包含数组所有键值对的 @@iterator

  1. let myRntries = numbers.entries();
  2. console.log(myRntries.next().value); // [ 0, 1 ]
  3. console.log(myRntries.next().value); // [ 1, 2 ]
  4. console.log(myRntries.next().value); // [ 2, 3 ]
  5. // ...
  6. myRntries = numbers.entries();
  7. for (const n of myRntries) {
  8. console.log(n);
  9. }
  10. // [ 0, 1 ] [ 1, 2 ] [ 2, 3 ] [ 0, 1 ] [ 1, 2 ] [ 2, 3 ] [ 3, 4 ] [ 4, 5 ] [ 5, 6 ]
  11. // [ 6, 7 ] [ 7, 8 ] [ 8, 9 ] [ 9, 10 ] [ 10, 11 ] [ 11, 12 ] [ 12, 13 ] [ 13, 14 ] [ 14, 15 ]

迭代器 keys()

keys() 方法迭代(返回包含数组所有索引的 @@iterator

  1. let myKeys = numbers.keys();
  2. console.log(myKeys.next()); // { value: 0, done: false }
  3. console.log(myKeys.next()); // { value: 1, done: false }
  4. console.log(myKeys.next()); // { value: 2, done: false }
  5. // ...
  6. myKeys = numbers.keys();
  7. for (const n of myKeys) {
  8. console.log(n);
  9. }
  10. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

迭代器 values()

values() 方法迭代(返回包含数组所有值的 @@iterator

  1. let myValues = numbers.values();
  2. console.log(myValues.next()); // { value: 1, done: false }
  3. console.log(myValues.next()); // { value: 2, done: false }
  4. console.log(myValues.next()); // { value: 3, done: false }
  5. // ...
  6. myValues = numbers.values();
  7. for (const n of myValues) {
  8. console.log(n);
  9. }
  10. // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

@@iterator

使用 @@iterator (返回一个包含数组键值对的迭代器对象,可以通过同步调用得到数组元素的键值对)

  1. let myIterator = numbers[Symbol.iterator]();
  2. console.log(myIterator.next().value); // 1
  3. console.log(myIterator.next()); // { value: 2, done: false }
  4. console.log(myIterator.next().value); // 2
  5. console.log(myIterator.next().value); // 3
  6. console.log(myIterator.next().value); // 4
  7. console.log(myIterator.next().value); // 5
  8. // ...
  9. myIterator = numbers[Symbol.iterator]();
  10. for (const n of myIterator) {
  11. console.log(n);
  12. }
  13. // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

创建一个新数组 from()Array.of()

创建一个新数组 from()

使用 from() 方法(根据已有数组创建一个新的数组)

  1. let numbers2 = Array.from(numbers); // 复制 numbers 数组
  2. console.log(numbers2);
  3. let evens = Array.from(numbers, x => (x % 2) == 0); // 传入一个用来过滤值得函数)
  4. console.log(evens);

创建一个新数组 Array.of()

使用 Array.of() 方法(根据传入得参数创建一个新数组)

  1. let numbers3 = [1];
  2. let numbers4 = [1, 2, 3, 4, 5,];
  3. let numbersCopy = Array.from(numbers4);

下面 3 行代码等效于上面 3 行代码

  • 使用 Array.of() 方法 复制已有的数组
  • 展开运算符(...)会把 numbers4 数组里得值都展开成参数
  1. let numbers3 = Array.of(1);
  2. let numbers4 = Array.of(1, 2, 3, 4, 5,);
  3. let numbersCopy = Array.of(...numbers4);
  1. console.log(numbers3); // [ 1 ]
  2. console.log(numbers4); // [ 1, 2, 3, 4, 5 ]
  3. console.log(numbersCopy); // [ 1, 2, 3, 4, 5 ]

填充数组 fill()

注意:会改变原始数组,所以应特别注意

  1. let fillNumbers = Array.of(1, 2, 3, 4, 5, 6);

所有的都填充为 0

  1. let myFill = fillNumbers.fill(0);
  2. console.log(myFill); // [ 0, 0, 0, 0, 0, 0 ]

指定开始填充得索引,从 1 开始得所有位置都填充为 2

  1. let myFill = fillNumbers.fill(2, 1);
  2. console.log(myFill); // [ 0, 2, 2, 2, 2, 2 ]

指定结束填充的索引,把 1 填充到数组索引 3 到 5 的位置(包括 3 不包括 5)

  1. let myFill = fillNumbers.fill(1, 3, 5);
  2. console.log(myFill); // [ 0, 2, 2, 1, 1, 2 ]

创建数组并初始化值得时候,fill() 方法非常好用

  1. let ones = Array(6).fill(1);
  2. console.log(ones); // [ 1, 1, 1, 1, 1, 1 ]

复制数组元素 copyWithin()

使用 copyWithin() 方法(复制数组中一系列元素到同一数组指定的起始位置)

注意:会改变原始数组,所以应特别注意

  1. let copyArray = [1, 2, 3, 4, 5, 6];

例如:把 4、5、6 三个值复制到数组前三个位置

  1. let myCopyWithin = copyArray.copyWithin(0, 3);
  2. console.log(myCopyWithin); // [ 4, 5, 6, 4, 5, 6 ]

把 从位置 3 开始到位置 5(包括 3 不包括 5)的元素复制到位置 1

  1. let myCopyWithin = copyArray.copyWithin(1, 3, 5);
  2. console.log(myCopyWithin); // [ 4, 4, 5, 4, 5, 6 ]

数组元素排序

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

数组元素排序 reverse()

使用 reverse() 方法(反序输入数组)

  1. let myReverse = numbers.reverse();
  2. console.log(myReverse); // [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

数组元素排序 sort()

  • 不传参数直接使用 sort() 方法

sort() 方法在对数组做排序时,把元素默认成字符串进行相互比较

  1. let mySort = numbers.sort();
  2. console.log(mySort); // [1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9]
  • 传入自己写的比较函数
  1. mySort = numbers.sort((a, b) => a - b);
  2. console.log(mySort); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

b > a 时,这段代码会返回负数,反之则返回正数,相等就返回 0,这样 sort() 方法就能根据返回值的情况对数组进行排序

另一种实现方式

  1. function compare(a, b) {
  2. if (a < b) {
  3. return -1;
  4. }
  5. if (a > b) {
  6. return 1;
  7. }
  8. return 0;
  9. }
  10. mySort = numbers.sort(compare);
  11. console.log(mySort); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
  • 自定义排序 —— 对任何对象类型的数组排序
  1. const friends = [
  2. { name: 'John', age: 20 },
  3. { name: 'Charles', age: 22 },
  4. { name: 'Bruce', age: 18 },
  5. ];
  6. function comparePerson(a, b) {
  7. if (a.age < b.age) {
  8. return -1;
  9. }
  10. if (a.age > b.age) {
  11. return 1;
  12. }
  13. return 0;
  14. }
  15. console.log(friends.sort(comparePerson));
  16. /*
  17. [
  18. { 'name': 'Bruce', 'age': 18 },
  19. { 'name': 'John', 'age': 20 },
  20. { 'name': 'Charles', 'age': 22 }
  21. ]
  22. */
  • 字符串排序
  1. let names = ['Ana', 'ana', 'john', 'John'];
  2. console.log(names.sort()); // ['Ana', 'John', 'ana', 'john']

忽略大小写进行排序

  1. function compareString(a, b) {
  2. if (a.toLowerCase() < b.toLowerCase()) {
  3. return -1;
  4. }
  5. if (a.toLowerCase() > b.toLowerCase()) {
  6. return 1;
  7. }
  8. return 0;
  9. }
  10. console.log(names.sort(compareString)); // ['Ana', 'ana', 'John', 'john']

按照大小写字母顺序排序,小写排在前面

  1. let mySortString = names.sort((a, b) => a.localeCompare(b));
  2. console.log(mySortString); // ['ana', 'Ana', 'john', 'John']

假如对带有重音符号的字符做排序的话,也可以用 localeCompare 来实现

数组元素搜索

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 10, 15];

数组元素搜索 indexOf()lastIndexOf()

  • indexOf() 方法(返回与参数匹配的第一个元素的索引,没有匹配上返回 -1)
  • lastIndexOf() 方法(返回与参数匹配的最后一个元素的索引,没有匹配上返回 -1)
  1. console.log(numbers.indexOf(10)); // 9
  2. console.log(numbers.indexOf(100)); // -1
  3. console.log(numbers.lastIndexOf(10)); // 13
  4. console.log(numbers.lastIndexOf(100)); // -1

数组元素搜索 find()findIndex()

  • find() 方法(接受一个回调函数,搜索一个满足回调函数条件的值,没有搜索到满足条件的情况下返回 undefined
  • findIndex() 方法(接受一个回调函数,搜索一个满足回调函数条件的索引,没有搜索到满足条件的情况下返回 -1)
  1. function multipleOf3(element, index, array) {
  2. return element % 3 == 0;
  3. }
  4. console.log(numbers.find(multipleOf3)); // 3
  5. console.log(numbers.findIndex(multipleOf3)); // 2

数组元素搜索 includes()

includes() 方法(如果数组里存在某个元素,includes() 方法会返回 true,否子返回 false

  1. console.log(numbers.includes(15)); // true
  2. console.log(numbers.includes(20)); // false
  3. // 传入一个起始索引,搜索会从索引指定的位置开始
  4. console.log(numbers.includes(4, 5)); // false(索引 5 之后的元素不包含 4)

输出数组为字符串 toString()join()

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 10, 15];
  2. console.log(numbers.toString()); // 1,2,3,4,5,6,7,8,9,10,11,12,13,10,15
  3. console.log(numbers.join('-')); // 1-2-3-4-5-6-7-8-9-10-11-12-13-10-15

类型数组

类型数组 数据类型
Int8Array 8 位二进制补码整数
Uint8Array 8 位无符号整数
Uint8ClampedArray 8 位无符号整数
Int16Array 16 位二进制补码整数
Uint16Array 16 位无符号整数
Int32Array 32 位二进制补码整数
Uint32Array 32 位无符号整数
Float32Array 32 位IEEE浮点数
Float64Array 64 位IEEE浮点数
  1. let length = 50;
  2. let int16 = new Int16Array(length);
  3. let array16 = [];
  4. array16.length = length;
  5. for (let i = 0; i < length; i++) {
  6. int16[i] = i + 1;
  7. }
  8. console.log(int16);
  9. /*
  10. Int16Array [
  11. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  12. 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  13. 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
  14. 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
  15. 45, 46, 47, 48, 49, 50
  16. ]
  17. */