JavaScript 数据结构与算法——第 1 章 数组

本文详细介绍了JavaScript中数组的创建、初始化、访问元素、迭代、添加和删除元素的方法,包括push、pop、unshift、shift等。此外,还探讨了二维数组、多维数组的处理以及数组的高级操作,如concat、every、some、forEach、map、filter、reduce等方法的使用,以及自定义排序和搜索方法。通过实例解析,帮助读者深入掌握JavaScript数组的使用技巧。
摘要由CSDN通过智能技术生成

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();

通过 pushpop 方法,就能用数组来模拟栈

1.3.2 从数组首位删除元素

可以循环数组中的元素,从第一位开始,让它后一个元素的值赋给它,依次处理。

for (let i = 0; i < numbers.length; i++) {
  numbers[i] = numbers[i+1];
}

这样做实质上是把数组里的元素都左移了一位,数组的长度依然未变,这意味着数组有额外的元素(值是undefined)。

要确实删除数组的第一个元素,可以使用 shift 方法:

numbers.shift();

通过 unshiftshift 方法,就能用数组来模拟基本的队列数据结构


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 方法接收一个函数作为参数,这个函数有四个参数:previousValuecurrentValueindexarray。这个函数会返回一个将被叠加到累加器的值,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—— findfindIndex 方法
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));

findfindIndex 方法接收一个回调函数,搜索一个满足回调函数条件的值。上面的例子中,要从数组中找到一个 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值