JavaScript 中的数组应用

本篇是关于 JavaScript 中 数组的有关用法 所编写的

目录

1. 为什么要使用数组

2. 如何声明一个数组

3.向数组中添加元素

在数组中添加和删除元素也很容易,但有时也会很棘手。假如我们有一个数组 numbers,

3.1 数组末尾添加一个元素

3.2 在数组开头添加一个元素

4 删除一个元素

4.1 从数组末尾删除元素

4.2 从数组开头删除元素

5. 在任意位置插入删除元素

6.JavaScript 的数组方法参考

6.1数组合并

6.2 迭代器函数

7. ECMAScript 6 和数组的新功能

7.1. 使用 for...of 循环迭代

7.2 使用@@iterator 对象

7.3 数组的 entries、keys 和 values 方法

7.4 使用 from 方法

7.5. 使用 Array.of 方法

7.6 使用 fill 方法(数组中的填充)

7.7 使用 copyWithin 方法

7.8 数组元素的排序

7.9 搜索

7.10 列表元素字符传拼接


1. 为什么要使用数组

//假如有这样一个需求:保存所在城市每个月的平均温度。可以这么做:
const averageTempJan = 31.9;
const averageTempFeb = 35.3;
const averageTempMar = 42.4;
const averageTempApr = 52;
const averageTempMay = 60.8;

当然,这肯定不是最好的方案。按照这种方式,如果只存一年的数据,我们能管理 12 个变量。
若要多存几年的平均温度呢?幸运的是,我们可以用数组来解决,更加简洁地呈现同样的信息。
const averageTemp = []; 
averageTemp[0] = 31.9; 
averageTemp[1] = 35.3; 
averageTemp[2] = 42.4; 
averageTemp[3] = 52; 
averageTemp[4] = 60.8;

2. 如何声明一个数组

let arr = new Array()
let arr1 = new Array(7)
let arr2 = new Array(1,2,3,4,5)
//使用new 关键字声明 
console.log(arr2)

// 使用字面量直接声明 这两个 的结果是一样的
let arr3= [] 


//如果想知道一个数组的长度  , 每一个数组中都有一个 length属性  
console.log(arr1.length)//5

访问元素和迭代数组(数组其实就是一个容器 , 就是能存贮 我们一个任意的 数据类型 , 然后方便我们以后去使用)

既然我们创建了一个数组 ,那么我们怎么才能访问到数组里面的变量呢

let daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 
'Friday', 'Saturday'];
// 可以使用for 循环来 遍历 数组中的每一个元素

for (let i = 0 ;i < daysOfWeek.length; i++ ){
console.log(daysOfWeek[i])
}

//我们来看另一个例子:求斐波那契数列的前 20 个数。已知斐波那契数列中的前两项是 1,
从第三项开始,每一项都等于前两项之和。

let fibonacci = []

for (let i = 0 ;i<20;i++ ){
    if (i===0||i===1){
        fibonacci[i]=1
    }else {
        fibonacci[i]=fibonacci[i-1]+fibonacci[i-2]
    }
}
console.log(fibonacci)
console.log(fibonacci.length)
// [
//     1,    1,    2,    3,    5,
//     8,   13,   21,   34,   55,
//    89,  144,  233,  377,  610,
//   987, 1597, 2584, 4181, 6765
// ]
// 20

3.向数组中添加元素

在数组中添加和删除元素也很容易,但有时也会很棘手。假如我们有一个数组 numbers,
初始化成了 0 9
//在下面的数组开头中添加 -1 
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (let i=numbers.length; i>=0;i--){
    numbers[i]=numbers[i-1]

}

numbers[0]=-1
console.log( numbers)

3.1 数组末尾添加一个元素

如果想要给数组添加一个元素(比如 10 ),只要把值赋给数组中最后一个空位上的元素即可。
numbers[numbers.length] = 10;
使用 push 方法
另外,还有一个 push 方法,能把元素添加到数组的末尾。通过 push 方法,我们能添加任 意个元素。
numbers.push(11);
numbers.push(12, 13);
如果输出 numbers 的话,就会看到从 0 13 的值。

3.2 在数组开头添加一个元素

 如果想要再数组开头添加一个元素 我们只能 是吧每一个元素 向后挪一位 然后把把添加的元素赋值给开头的位置

使用 unshift 方法
JavaScript 里,数组有一个方法叫 unshift ,可以直接把数值插入数组的开头(此方法背
后的逻辑和 insertFirstPosition 方法的行为是一样的)。
numbers.unshift(-2);
numbers.unshift(-4, -3);

4 删除一个元素

目前为止,我们已经学习了如何给数组的开始和结尾位置添加元素。下面来看一下怎样从数
组中删除元素。

4.1 从数组末尾删除元素

要删除数组里最靠后的元素,可以用 pop 方法。
numbers.pop();

4.2 从数组开头删除元素

如果要移除数组里的第一个元素,可以用下面的代码。
for (let i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i + 1];
}
我们把数组里所有的元素都左移了一位,但数组的长度依然是 17,这意味着数组中有额外 的一个元素(值是 undefined)。在最后一次循环里 里, i+1 引用了数组里还未初始化的一个位置。
Java C/C+ C# 等一些语言里,这样写可能会抛出异常,因此不得不在 numbers.length- 1
处停止循环
要从数组中移除这个值,还可以创建一个包含刚才所讨论逻辑的方法,叫作 removeFirst
Position 。但是,要真正从数组中移除这个元素,我们需要创建一个新的数组,将所有不是
undefined 的值从原来的数组复制到新的数组中,并且将这个新的数组赋值给我们的数组。要
完成这项工作,也可以像下面这样创建一个 reIndex 方法。
Array.prototype.reIndex = function(myArray) {
const newArray = [];
for(let i = 0; i < myArray.length; i++ ) {
if (myArray[i] !== undefined) {
// console.log(myArray[i]);
newArray.push(myArray[i]);
}
}
return newArray;
}

5. 在任意位置插入删除元素

目前为止,我们已经学习了如何添加元素到数组的开头或末尾,以及怎样删除数组开头和结
尾位置上的元素。那么如何在数组中的任意位置上删除或添加元素呢?
我们可以使用 splice 方法,简单地通过指定位置 / 索引,就可以删除相应位置上指定数量
的元素。
numbers.splice(5,3);
这行代码删除了从数组索引 5 开始的 3 个元素。这就意味着 numbers[5] numbers[6]
numbers[7] 从数组中删除了。现在数组里的值变成了 3 2 1 0 1 5 6 7 8 9 10
11 12 2 3 4 已经被移除)。
对于 JavaScript 数组和对象,我们还可以用 delete 运算符删除数组中的元素,
例如 delete numbers[0] 。然而,数组位置 0 的值会变成 undefined ,也就
是说,以上操作等同于 numbers[0] = undefined 。因此,我们应该始终使用
splice pop shift (马上就会学到)方法来删除数组元素。
现在,我们想把数 2 3 4 插入数组里,放到之前删除元素的位置上,可以再次使用 splice
方法。
numbers.splice(5, 0, 2, 3, 4);
splice 方法接收的第一个参数,表示想要删除或插入的元素的索引值。第二个参数是删除
元素的个数(这个例子里,我们的目的不是删除元素,所以传入 0 )。第三个参数往后,就是要
添加到数组里的值(元素 2 3 4 )。输出会发现值又变成了从 3 12
最后,执行以下这行代码。
numbers.splice(5, 3, 2, 3, 4);
输出的值是从 3 12 。原因在于,我们从索引 5 开始删除了 3 个元素,但也从索引 5 开始
添加了元素 2 3 4

6.JavaScript 的数组方法参考

6.1数组合并

const zero = 0;
const positiveNumbers = [1, 2, 3];
const negativeNumbers = [-3, -2, -1];
let numbers = negativeNumbers.concat(zero, positiveNumbers);
concat 方法可以向一个数组传递数组、对象或是元素。数组会按照该方法传入的参数顺序
连接指定数组。在这个例子里, zero 将被合并到 nagativeNumbers 中,然后 positiveNumbers
继续被合并。最后输出的结果是 3 2 1 0 1 2 3

6.2 迭代器函数

有时,我们需要迭代数组中的元素。前面已经学过,可以用循环语句来处理,例如 for 语句。
JavaScript 内置了许多数组可用的迭代方法。对于本节的例子,我们需要一个数组和一个函
数:假设数组中的值是从 1 15 ;如果数组里的元素可以被 2 整除(偶数),函数就返回 true
否则返回 false
function isEven(x) {
// 如果 x 2 的倍数,就返回 true
console.log(x);
return x % 2 === 0 ? true : false;
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
简化代码
const isEven = x => x % 2 === 0;

1. every 方法迭代
我们要尝试的第一个方法是 every every 方法会迭代数组中的每个元素,直到返回 false
numbers.every(isEven);
在这个例子里,数组 numbers 的第一个元素是 1 ,它不是 2 的倍数( 1 是奇数),因此 isEven
函数返回 false ,然后 every 执行结束。

2.用 some 方法迭代
下一步,我们来看 some 方法。它和 every 的行为相反,会迭代数组的每个元素,直到函
数返回 true
numbers.some(isEven);
在我们的例子里, numbers 数组中第一个偶数是 2 (第二个元素)。第一个被迭代的元素
1 isEven 会返回 false 。第二个被迭代的元素是 2 isEven 返回 true —— 迭代结束。
3. forEach 方法迭代
如果要迭代整个数组,可以用 forEach 方法。它和使用 for 循环的结果相同。
numbers.forEach(x => console.log(x % 2 === 0));
4.JavaScript 还有两个会返回新数组的迭代方法。第一个是 map
const myMap = numbers.map(isEven); (返回一个函数执行的返回值组成的数组)
数组 myMap 里的值是: [false, true, false, true, false, true, false, true,
false, true, false, true, false, true, false] 。它保存了传入 map 方法的 isEven
函数的运行结果。这样就很容易知道一个元素是否是偶数。比如, myMap[0] false ,因为 1
不是偶数;而 myMap[1] true ,因为 2 是偶数。
5. filter ( 返沪所有执行函数为true 的元素)
还有一个 filter 方法,它返回的新数组由使函数返回 true 的元素组成。
const evenNumbers = numbers.filter(isEven);
在我们的例子里, evenNumbers 数组中的元素都是偶数: [2, 4, 6, 8, 10, 12, 14]
6. 使用 reduce 方法(
    • 减少;降低:例如,减少浪费(reduce waste)、降低亮度(reduce luminance)、减少成本(Reduce costs)。
    • 使处于:使某人/某事物陷入某种(通常指更坏的)状态或状况中。
    • 把...分解:将某事物概括或简化成某种形式,或将化合物还原。

最后是 reduce 方法。 reduce 方法接收一个有如下四个参数的函数: previousValue
currentValue index array 。因为 index array 是可选的参数,所以如果用不到它们
的话,可以不传。这个函数会返回一个将被叠加到累加器的值, reduce 方法停止执行后会返回
这个累加器。如果要对一个数组中的所有元素求和,这就很有用。下面是一个例子。
numbers.reduce((previous, current) => previous + current);
输出将是 120
let numbers = [1,2,3,4,5,6,7,8,9]
let res = numbers.reduce((sum,next)=>{
    sum=sum+next
    return sum
},0)
console.log(res)

7. ECMAScript 6 和数组的新功能

7.1. 使用 for...of 循环迭代

你已经学过用 for 循环和 forEach 方法迭代数组。 ES2015 还引入了迭代数组值的
for...of 循环,下面来看看它的用法。
for (const n of numbers) {
console.log(n % 2 === 0 ? 'even' : 'odd');
}
let numbers = [1,2,3,4,5,6,7,8,9]

for(let i in numbers){
    console.log(i)
}
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8

7.2 使用@@iterator 对象

ES2015 还为 Array 类增加了一个 @@iterator 属性,需要通过 Symbol.iterator 来访问。
代码如下。
let iterator = numbers[Symbol.iterator]();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
console.log(iterator.next().value); // 4
console.log(iterator.next().value); // 5
然后,不断调用迭代器的 next 方法,就能依次得到数组中的值。 numbers 数组中有 15
我们可以用下面的代码来输出 numbers 数组中的 15 个值。
iterator = numbers[Symbol.iterator]();
for (const n of iterator) {
console.log(n);}

7.数组的 entrieskeys values 方法

ES2015 还增加了三种从数组中得到迭代器的方法。我们首先要学习的是 entries 方法。
entries 方法返回包含键值对的 @@iterator ,下面是使用该方法的代码示例。
let aEntries = numbers.entries(); // 得到键值对的迭代器
console.log(aEntries.next().value); // [0, 1] - 位置 0 的值为 1
console.log(aEntries.next().value); // [1, 2] - 位置 1 的值为 2
console.log(aEntries.next().value); // [2, 3] - 位置 2 的值为 3
numbers 数组中都是数, key 是数组中的位置, value 是保存在数组索引的值。
我们也可以使用下面的代码。
aEntries = numbers.entries();
for (const n of aEntries) {
console.log(n);
}
使用集合、字典、散列表等数据结构时,能够取出键值对是很有用的。这个功能会在本书后
面的章节中大显身手。
keys 方法返回包含数组索引的 @@iterator ,下面是使用该方法的代码示例。
const aKeys = numbers.keys(); // 得到数组索引的迭代器
console.log(aKeys.next()); // {value: 0, done: false }
console.log(aKeys.next()); // {value: 1, done: false }
console.log(aKeys.next()); // {value: 2, done: false }
keys 方法会返回 numbers 数组的索引。一旦没有可迭代的值, aKeys.next() 就会返回一
value 属性为 undefined done 属性为 true 的对象。如果 done 属性的值为 false ,就意
味着还有可迭代的值。
values 方法返回的 @@iterator 则包含数组的值。使用这个方法的代码示例如下。
const aValues = numbers.values();
console.log(aValues.next()); // {value: 1, done: false }
console.log(aValues.next()); // {value: 2, done: false }
console.log(aValues.next()); // {value: 3, done: false }

7.4 使用 from 方法

Array.from 方法根据已有的数组创建一个新数组。比如,要复制 numbers 数组,可以如
下这样做。
let numbers2 = Array.from(numbers);
还可以传入一个用来过滤值的函数,例子如下。
let evens = Array.from(numbers, x => (x % 2 == 0));
上面的代码会创建一个 evens 数组,以及值 true (如果在原数组中为偶数)或 false (如
果在原数组中为奇数)。

7.5. 使用 Array.of 方法

Array.of 方法根据传入的参数创建一个新数组。以下面的代码为例。
let numbers3 = Array.of(1);
let numbers4 = Array.of(1, 2, 3, 4, 5, 6);
它和下面这段代码的效果一样。
let numbers3 = [1];
let numbers4 = [1, 2, 3, 4, 5, 6];
我们也可以用该方法复制已有的数组,如下所示。
let numbersCopy = Array.of(...numbers4);
上面的代码和 Array.from(numbers4) 的效果是一样的,区别只是用到了第 1 章讲过的展
开运算符。展开运算符( ... )会把 numbers4 数组里的值都展开成参数。

7.6 使用 fill 方法(数组中的填充)

fill 方法用静态值填充数组。以下面的代码为例。
let numbersCopy = Array.of(1, 2, 3, 4, 5, 6);
numbersCopy 数组的 length 6 ,也就是有 6 个位置。再看下面的代码。
numbersCopy.fill(0);
numbersCopy 数组所有位置上的值都会变成 0 [0, 0, 0, 0, 0, 0] )。我们还可以指定
开始填充的索引,如下所示。 60 3 章 数组
numbersCopy.fill(2, 1);
上面的例子里,数组中从 1 开始的所有位置上的值都是 2 [0, 2, 2, 2, 2, 2] )。
同样,我们也可以指定结束填充的索引。
numbersCopy.fill(1, 3, 5);
在上面的例子里,我们会把 1 填充到数组索引 3 5 的位置(不包括 3 5 ),得到的数组为
[0, 2, 2, 1, 1, 2]

7.7 使用 copyWithin 方法

copyWithin 方法复制数组中的一系列元素到同一数组指定的起始位置。看看下面这个例子。
let copyArray = [1, 2, 3, 4, 5, 6];
假如我们想把 4 5 6 三个值复制到数组前三个位置,得到 [4, 5, 6, 4, 5, 6] 这个数
组,可以用下面的代码达到目的。
copyArray.copyWithin(0, 3);
假如我们想把 4 5 两个值(在位置 3 4 上)复制到位置 1 2 ,可以这样做:
copyArray = [1, 2, 3, 4, 5, 6];
copyArray.copyWithin(1, 3, 5);
这种情况下,会把从位置 3 开始到位置 5 结束(不包括 3 5 )的元素复制到位置 1 ,结果
是得到数组 [1, 4, 5, 4, 5, 6]

copyWithin 是 JavaScript 数组的一个方法,用于在当前数组内部,将指定位置的成员复制到其他位置,并返回当前数组。这个方法会修改原数组。

copyWithin 方法接受三个参数,每个参数的含义如下:

  1. target (必需)
    • 定义从哪个位置开始替换数组的元素。
    • 如果该值为负数,则表示从末尾开始计算的索引。例如,-1 表示最后一个元素,-2 表示倒数第二个元素,依此类推。
    • 如果 target 大于等于数组的长度,将不会进行任何拷贝操作。
  2. start (可选)
    • 定义从哪个位置开始读取元素进行复制。
    • 如果省略此参数,默认为 0。
    • 如果该值为负数,则表示从末尾开始计算的索引。
    • 如果 start 大于等于数组的长度,则 start 会被当作数组长度处理。
    • 如果 start 大于 end,则不会进行任何拷贝操作。
  3. end (可选)
    • 定义到哪个位置前停止读取元素进行复制(不包含该位置的元素)。
    • 如果省略此参数,默认为数组的长度。
    • 如果该值为负数,则表示从末尾开始计算的索引。
    • 如果 end 大于数组的长度,则 end 会被当作数组长度处理。

示例

假设我们有一个数组 arr = [1, 2, 3, 4, 5]

  • arr.copyWithin(0, 3):这将从索引 3 开始(即元素 4)到数组末尾的元素复制到索引 0 的位置开始,结果是 [4, 5, 3, 4, 5]
  • arr.copyWithin(1, -2, -1):这将从倒数第二个元素(即元素 4)复制到索引 1 的位置开始,但不包括倒数第一个元素(即元素 5),结果是 [1, 4, 3, 4, 5]

注意:

  • 这三个参数都应该是数值,如果不是,它们会被自动转换为数值。
  • 如果 start 大于 end,则不会进行任何拷贝操作。
  • copyWithin 方法会直接修改原数组,并返回修改后的数组。

7.8 数组元素的排序

通过本书,我们能学到如何编写最常用的搜索和排序算法。其实, JavaScript 里也提供了一
个排序方法和一组搜索方法。让我们来看看。
首先,我们想反序输出数组 numbers (它本来的排序是 1, 2, 3, 4, ..., 15 )。要实现
这样的功能,可以用 reverse 方法,然后数组内元素就会反序。
numbers.reverse();
现在,输出 numbers 的话就会看到 [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
2, 1] 。然后,我们使用 sort 方法。
numbers.sort();
然而,如果输出数组,结果会是 [1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8,
9] 。看起来不大对,是吧?这是因为 sort 方法在对数组做排序时,把元素默认成字符串进行相
互比较。

7.9 搜索

find 静态方法 (传入的参数是一个函数)

1. ECMAScript 2015—— 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);
}
console.log(numbers.find(multipleOf13));
console.log(numbers.findIndex(multipleOf13));
find findIndex 方法接收一个回调函数,搜索一个满足回调函数条件的值。上面的例子
里,我们要从数组里找一个 13 的倍数。
find findIndex 的不同之处在于, find 方法返回第一个满足条件的值, findIndex
方法则返回这个值在数组里的索引。如果没有满足条件的值, find 会返回 undefined ,而
findIndex 返回 -1
2. ECMAScript 7—— 使用 includes 方法
如果数组里存在某个元素, includes 方法会返回 true ,否则返回 false 。使用 includes
方法的例子如下。
console.log(numbers.includes(15));
console.log(numbers.includes(20));
例子里的 includes(15) 返回 true includes(20) 返回 false ,因为 numbers 数组里没
20 64 3 章 数组
如果给 includes 方法传入一个起始索引,搜索会从索引指定的位置开始。
let numbers2 = [7,6,5,4,3,2,1];
console.log(numbers2.includes(4,5));
上面的例子输出为 false ,因为数组索引 5 之后的元素不包含 4 (第一个参数 是查找的元素 第二个值是 查找的起始索引)

7.10 列表元素字符传拼接

现在,我们学习最后两个方法: toString join
如果想把数组里所有元素输出为一个字符串,可以用 toString 方法。
console.log(numbers.toString());
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 10 这些值都会在控制台中输出。
如果想用一个不同的分隔符(比如 - )把元素隔开,可以用 join 方法。
const numbersString = numbers.join('-');
console.log(numbersString);
输出将如下所示。
1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-10
如果要把数组内容发送到服务器,或进行编码(知道了分隔符,解码也很容易),这会很
有用。
  • 12
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值