1、数组的创建
(1)数组的组成
数组构成:数组由一个或多个数组元素组成的,各元素之间使用逗号“,”分割。
数组元素:每个数组元素由“下标”和“值”构成。
下标:又称索引,以数字表示,默认从0开始依次递增,用于识别元素。
值:元素的内容,可以是任意类型的数据,如数值型、字符型、数组、对象等。
数组还可以根据维数划分为一维数组、二维数组、三维数组等多维数组。
一维数组:就是指数组的“值”是非数组类型的数据,如上图。
二维数组:是指数组元素的“值”是一个一维数组,如下图。
多维数组:当一个数组的值又是一个数组时,就可以形成多维数组。它通常用于描述一些信息。
(2)数组的创建方式
实例化Array对象的方式。
实例化Array对象的方式创建数组,是通过new关键字实现的。
<script>
// 元素值类型为字符串
var area = new Array('Beijing', 'Shanghai', 'Shenzhen');
// 元素值类型为数值型
var score = new Array(56, 68, 98, 44);
// 元素值类型为混合型
var mix = new Array(123, 'abc', null, true, undefined);
// 空数组
var arr1 = new Array(); 或 var arr2 = new Array;
</script>
直接使用“[]”的方式。
直接法“[]”与Array()对象的使用方式类似,只需将new Array()替换为[]即可。
<script>
var weather = ['wind', 'fine',]; // 相当于:new Array('wind', 'fine',)
var empty = []; // 相当于:new Array
// 控制台输出mood:(5) ["sad", empty × 3, "happy"]
var mood = ['sad', , , ,'happy'];
</script>
直接法“[]”与Array()对象在创建数组时的区别在于,前者可以创建含有空存储位置的数组,而后者不可以。
2、数组的基本操作
(1)获取数组长度
Array对象提供的length属性可以获取数组的长度,其值为数组元素最大下标加1。
<script>
var arr1 = [78, 88, 98];
var arr2 = ['a', , , , 'b', 'c'];
console.log(arr1.length); // 输出结果为:3
console.log(arr2.length); // 输出结果为:6
//数组arr2中没有值的数组元素会占用空的存储位置。
//因此,数组的下标依然会递增。从而arr2调用length属性最后的输出结果即为6。
</script>
数组的length属性不仅可以用于获取数组长度,还可以修改数组长度。
在利用length属性指定数组长度时,有以下是三种情况:
<script>
var arr1 = [];
arr1.length = 5;
console.log(arr1); // 输出结果:(5) [empty × 5]
var arr2 = [1, 2, 3];
arr2.length = 4;
console.log(arr2); // 输出结果:(4) [1, 2, 3, empty]
var arr3 = ['a', 'b'];
arr3.length = 2;
console.log(arr3); // 输出结果:(2) ["a", "b"]
var arr4 = ['hehe', 'xixi', 'gugu', 'jiujiu'];
arr4.length = 3;
console.log(arr4); // 输出结果:(3) ["hehe", "xixi", "gugu"
</script>
除此之外,在利用Array对象方式创建数组时,也可以指定数组的长度。
<script>
var arr = new Array(3);
console.log(arr); // 输出结果:(3) [empty × 3]
</script>
注意:
JavaScript中不论何种方式指定数组长度后,并不影响继续为数组添加元素,同时数组的length属性值会发生相应的改变。
(2)数组的访问与遍历
数组元素访问方式:“数组名[下标]”。
遍历数组元素:依次访问数组中所有元素的操作。
<script>
//for...of
//变量value:表示每次遍历时对应的数组元素的值。
//变量arr:表示待遍历的数组。
var arr = [1, 2, 3];
for (var value of arr) {
console.log(value);
}
//for…in中的 i 指的是数组下标。
//for…in中的document表示数组的变量名称。
for(i in document){
console.log(document[i])
}
</script>
(3)数组元素的添加与修改
元素的添加与修改元素的方式:“数组名[下标]”。
<script>
// 为空数组添加元素
var height = [];
height[5] = 183;
height[0] = 175;
height[3] = 150;
console.log(height); // 输出结果:(6) [175, empty × 2, 150, empty, 183]
// 为非空数组添加元素
var arr = ['Asa', 'Taylor'];
arr[2] = 'Tom';
arr[3] = 'Jack';
console.log(arr); // 输出结果:(4) ["Asa", "Taylor", "Tom", "Jack"]
</script>
注意:
a、添加数组元素:数组名[下标] = 值。
b、允许下标不按照数字顺序连续添加,未设置具体值的元素,会以空存储位置的形式存在。
c、数组中元素保存顺序与下标有关,与添加元素的顺序无关。
修改元素与添加元素的使用相同,区别在于修改元素是为已含有值的元素重新赋值。
<script>
var arr = ['a', 'b', 'c', 'd'];
arr[2] = 123;
arr[3] = 456;
console.log(arr); // 输出结果:(4) ["a", "b", 123, 456]
</script>
(4)元素的删除
delete关键字只能删除数组中指定下标的元素值,删除后该元素依然会占用一个空的存储位置。
<script>
var stu = ['Tom', 'Jimmy', 'Lucy'];
console.log(stu); // 输出结果:(3) ["Tom", "Jimmy", "Lucy"]
delete stu[1]; // 删除数组中第2个元素
console.log(stu); // 输出结果:(3) ["Tom", empty, "Lucy"]
</script>
解构赋值
<script>
// 传统方式
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
</script>
<script>
//结构赋值方式
var arr = [1, 2, 3];
[a, b] = arr;
console.log(a + ' - ' + b); // 输出结果:1 - 2
//解构赋值时右侧的内容还可以是一个变量。
//通过解构赋值完成两个变量数值的交换。
var n1 = 4, n2 = 8;
[n1, n2] = [n2, n1];
console.log(n1 + ' - ' + n2); // 输出结果:8 - 4
</script>
当左侧变量的数量小于右侧的元素的个数,则忽略多余的元素。
当左侧变量数量大于右侧的元素个数时,则多余的变量会被初始化为undefined。
案例:查找最大值最小值
<script>
//查找最大值最小值
var arr = [100, 7, 65, 54, 12, 6]; // 待查找数组
var min = max = arr[0]; // 假设第1个元素为最大值和最小值
for (var i = 1; i < arr.length; ++i) {
if (arr[i] > max) { // 当前元素比最大值max大,则修改最大值
max = arr[i];
}
if (arr[i] < min) { // 当前元素比最小值min小,则修改最小值
min = arr[i];
}
}
console.log('待查找数组:' + arr);
console.log('最小值:' + min);
console.log('最大值:' + max);
</script>
3、常见二维数组操作
(1)创建与遍历
将数组元素设置为数组即可
<script>
// 使用Array对象创建数组
var info = new Array(new Array('Tom', 13, 155), new Array('Lucy', 11, 152));
var arr = new Array(new Array, new Array); // 空二维数组
// 使用“[]”创建数组
var num = [[1, 3], [2, 4]];
var empty = [[], []];
</script>
<script>
var arr = []; // 创建一维空数组
for (var i = 0; i < 3; ++i) {
//若要为二维数组元素(如arr[i][0])赋值,首先要保证添加的元素(如arr[i])已经被创建为数组,否则程序会报“Uncaught TypeError……”错误。
arr[i] = []; // 将当前元素设置为数组
arr[i][0] = i; // 为二维数组元素赋值
}
</script>
一维数组可以利用for、for…in或for…of(ES6提供)进行遍历。
二维数组只需在遍历数组后,再次遍历数组的元素即可。
<script>
var arr = [[12, 59, 66], [100, 888]]; // 待求和的二维数组
var sum = 0;
for (var i in arr) { // 遍历数组arr
for (var j in arr[i]) { // 遍历数组arr的元素
sum += arr[i][j]; // 二维数组元素累计相加
}
}
console.log('待求和的二维数组:' + arr);
console.log('二维数组arr求和等于:' + sum);
</script>
案例:二维数组转置
<script>
/*
代码实现思路:
找规律:res[0][0] = arr[0][0]、res[0][1] = arr[1][0]、res[0][2] = arr[2][0]。
得结论: res[i][j] = arr[j][i]。
res数组长度=arr元素(如arr[0])的长度。
res元素(如res[0])的长度=arr数组的长度。
按照③和④完成res的创建与遍历,按②进行转置。
*/
var arr = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['j', 'k', 'l']];
var res = [];
for (var i = 0; i < arr[0].length; ++i) { // 遍历res中的所有元素
res[i] = [];
for(var j = 0; j < arr.length; ++j){ // 遍历res元素中的所有元素
res[i][j] = arr[j][i]; // 为二维数组赋值
}
}
console.group('转置前:');
console.log(arr);
console.groupEnd();
console.group('转置后:');
console.log(res);
console.groupEnd();
</script>
4、数组排序
冒泡排序:是计算机科学领域中较简单的排序算法。
实现原理:在冒泡排序的过程中,按照要求从小到大排序或从大到小排序,不断比较数组中相邻两个元素的值,较小或较大的元素前移。
冒泡排序比较的轮数是数组长度减1,每轮比较的对数等于数组的长度减当前的轮数。
案例:冒泡排序
<script>
var arr = [10, 2, 5, 27, 98, 31];
console.log('待排序数组:' + arr);
for (var i = 1; i < arr.length; ++i) { // 控制需要比较的轮数
for (var j = 0; j < arr.length - i; ++j) { // 控制参与比较的元素
if (arr[j] > arr[j + 1]) { // 比较相邻的两个元素
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
console.log('排序后的数组:' + arr);
</script>
插入排序:也是冒泡排序的优化,是一种直观的简单排序算法。
实现原理:通过构建有序数组元素的存储,对于未排序的数组元素,在已排序的数组中从最后一个元素向第一个元素遍历,找到相应位置并插入。其中,待排序数组的第1个元素会被看作是一个有序的数组,从第2个至最后一个元素会被看作是一个无序数组。
按从小到大排序。
插入排序比较的次数与无序数组的长度相等。
案例:插入排序
<script>
var arr = [89, 56, 100, 21, 87, 45, 1, 888]; // 待排序数组
console.log('待排序数组:' + arr);
// 按照从小到大的顺序排列
for (var i = 1; i < arr.length; ++i) { // 遍历无序数组下标
for (var j = i; j > 0; --j) { // 遍历并比较 一个无序数组元素与所有有序数组元素
if (arr[j - 1] > arr[j]) {
[arr[j - 1], arr[j]] = [arr[j], arr[j - 1]];
}
}
}
// 输出从小到大排序后的数组
console.log('排序后的数组:' + arr);
</script>
5、常见数组方法
(1)栈和队列方法
JavaScript中,除了前面讲解的添加与删除数组元素的方式外,还可以利用Array对象提供的方法,模拟栈和队列的操作。
在数组的末尾或开头添加数组的新元素。
在数组的末尾或开头删除数组元素。
push()和unshift()方法的返回值是新数组的长度。
pop()和shift()方法返回的是移出的数组元素。
<script>
var arr = ['Rose', 'Lily'];
console.log('原数组:' + arr);
var last = arr.pop();
console.log('在末尾移出元素:' + last + ' - 移出后数组:' + arr);
var len = arr.push('Tulip', 'Jasmine');
console.log('在末尾添加元素后长度变为:' + len + ' - 添加后数组:' + arr);
var first = arr.shift();
console.log('在开头移出元素:' + first + ' - 移出后数组:' + arr);
len = arr.unshift('Balsam', 'sunflower');
console.log('在开头添加元素后长度变为:' + len + ' - 添加后数组:' + arr);
</script>
(2)检索方法
在开发中,若要检测给定的值是否是数组,或是查找指定的元素在数组中的位置。
表中除了Array.isArray()方法外,其余方法默认都是从指定数组索引的位置开始检索,且检索方式与运算符“===”相同,即只有全等时才会返回比较成功的结果。
includes()和Array.isArray()方法
<script>
var data = ['peach', 'pear', 26, '26', 'grape'];
// 从数组下标为3的位置开始检索数字26
console.log(data.includes(26, 3)); // 输出结果:false
// 从数组下标为data.length - 3 的位置查找数字26
console.log(data.includes(26, -3)); // 输出结果:true
// 判断变量data是否为数组
console.log(Array.isArray(data));
</script>
includes()方法的第1个参数表示待查找的值。
includes()方法的第2个参数用于指定在数组中查找的下标。
设置为大于数组长度时,数组不会被检索,直接返回false。
设置为小于0的数时,则检索的索引位置等于数组长度加上指定的负数,若结果仍是小于0的数,则检索整个数组。
**indexOf()**用于在数组中从指定下标位置,检索到的第一个给定值,存在则返回对应的元素下标,否则返回-1。
<script>
var arr = ['potato', 'tomato', 'chillies', 'green-pepper'];
var search = 'cucumber';
if (arr.indexOf(search) === -1) { // 查找的元素不存在
arr.push(search);
console.log('更新后的数组为: ' + arr);
} else if (arr.indexOf(search) > -1) { // 防止返回的下标为0,if判断为false
console.log(search + '元素已在arr数组中。');
}
</script>
indexOf()方法的第2个参数用于指定开始查找的下标:
当其值大于或等于数组长度时,直接返回-1。
当其值为负数时,则查找的下标位置等于数组长度加上指定的负数,若结果仍是小于0的数,则检索整个数组。
lastIndexOf()方法
Array对象提供的lastIndexOf()方法,用于在数组中从指定下标位置检索到的最后一个给定值的下标。与indexOf()检索方式不同的是,lastIndexOf()方法默认逆向检索,即从数组的末尾向数组的开头检索。
<script>
var res = [];
var arr = ['a', 'b', 'a', 'c', 'a', 'd']; // 待检索的数组
var search = 'a'; // 要查找的数组元素
var i = arr.lastIndexOf(search);
while (i !== -1) {
res.push(i);
i = (i > 0 ? arr.lastIndexOf(search, i - 1) : -1);
}
console.log('元素 ' + search + ' 在数组中的所有位置为:' + res);
</script>
lastIndexOf()方法的第2个参数用于指定查找的下标,且由于其采用逆向的方式检索:
当其值大于或等于数组长度时,则整个数组都会被查找。
当其值为负数时,则索引位置等于数组长度加上给定的负数,若其值仍为负数,则直接返回-1。
(3)数组转字符串
<script>
console.log(['a', , 'c'].join()); // 输出结果:a,b,c
console.log([[4, 5], [1, 2]].join('-')); // 输出结果:4,5-1,2
console.log(['a', 'b', 'c'].toString()); // 输出结果:a,b,c
console.log([[4, 5], [1, 2]].toString()); // 输出结果:4,5,1,2
</script>
join()和toString()方法的相同点:
可将多维数组转为字符串,默认情况下使用逗号连接。
当数组元素为undefined、null或空数组时,对应的元素会被转换为空字符串
join()和toString()方法的不同点。
join()方法可以指定连接数组元素的符号。
(4)其他方法
<script>
// sort 默认排序将元素转换为字符串,升序
var arr = [2,4,1,15,34,111];
console.log(arr.sort());
console.log(arr.sort(function(a,b){
return a-b;
// a-b 升序
// b-a 降序
}))
</script>
<script>
// fill 将固定值替换数组的元素,可以通过下标指定范围
// fill(value,start,end);end 默认数组长度
var arr =['lucy','justin','json','qq','ww','ee'];
arr.fill('lily');
console.log(arr);
arr.fill('jackson',2,5);
console.log(arr);
arr.fill('jack',5);
console.log(arr);
</script>
<script>
// reverse 颠倒数组元素位置
var arr = [11,22,33,44];
console.log(arr.reverse())
</script>
<script>
// splice 添加或者删除数组中的元素
// 1、删除 splice(index,num) 返回值 删除的内容
var arr = ['a','b','c','d'];
var res = arr.splice(1,2);
console.log(arr);
console.log(res);
// 2、插入 splice(index,0,value) 返回值:空数组
// 第一个参数:插入位置;第三个参数 插入的项;
var arr = ['a','b','c','d'];
var res = arr.splice(1,0,['re','er'],null,undefined,[]);
console.log(arr);
console.log(res);
// 3、替换 splice(index,num,value) 返回值:删除的内容
// 第一个参数 起始位置;第二个参数 删除的项数;第三个 插入的项(任意数量);
var arr = ['a','b','c','d'];
var res = arr.splice(1,1,'re','rs');
console.log(arr);
console.log(res);
</script>
<script>
// slice(start,end);
// start 必填设置新数组的起始位置负数表示从数组的尾部开始算,-1最后一个元素;
// end 可选 结束位置 默认数组结尾
var arr = [1,2,3,4,5];
// 仅包含最后一个元素
var res1 = arr.slice(-1);//5
console.log(arr);
console.log(res1);
// 不包含最后一个元素
var res2 = arr.slice(0,-1);//[1,2,3,4]
var res3 = arr.slice(1);//[2,3,4,5]
</script>
<script>
// concat 合并2个或者多个数组
var arr = [1,2,3].concat([4,5]);
console.log(arr);//[1,2,3,4,5];
var arr1 = [1,2];
var arr2 = [3,4];
var arr3 = [5,6];
var arr4 = arr1.concat(arr2,arr3);
console.log(arr4);//[1,2,3,4,5,6]
var arr1 = [1,2];
var arr2 = 3;
var arr3 = [5,6];
var arr4 = arr1.concat(arr2,arr3);
console.log(arr4);//[1,2,3,5,6]
</script>
<script>
var arr = ['sky', 'wind', 'snow', 'sun'];
// 从数组下标2的位置开始,删除2个元素
arr.splice(2, 2);
console.log(arr);
// 从数组下标1的位置开始,删除1个元素后,再添加snow元素
arr.splice(1, 1, 'snow');
console.log(arr);
// 指定下标4大于数组的长度,则直接在数组末尾添加hail和sun元素
arr.splice(4, 0, 'hail', 'sun');
console.log(arr);
// 从数组下标3的位置开始,添加数组、null、undefined和空数组
arr.splice(3, 0, ['lala', 'yaya'], null, undefined, []);
console.log(arr);
</script>
slice()和concat()方法在执行后返回一个新的数组,不会对原数组产生影响,剩余的方法在执行后皆会原数组产生影响。
splice()方法的第1个参数的值等于或大于数组长度时,从数组末尾开始操作;当该值为负数时,则下标位置等于数组长度加上指定的负数,若其值仍为负数,则从数组的开头开始操作。
案例:猴子选大王
<script>
/*
游戏规则:要求一群猴子排成一圈,按“1,2,……,n”依次编号。然后从第1只开始数,数到第m只,把它踢出圈,其后的猴子再从1开始数,数到第m只,再把它踢出去……,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就是我们要找的大王。
*/
var total = prompt('请输入猴子总数:');
var kick = prompt('踢出第几只猴子:');
var monkey = [];
for(var i = 1;i<=total;i++){
monkey.push(i);
}
i = 0;
while(monkey.length>1){
i++; //1 ,2,3
var num = monkey.shift();//1,2,3 [5,....,1,2,4]
if( i % kick != 0){
monkey.push(num);// [5,....,1,2,4]
}
}
console.log('猴王编号:'+monkey[0])
</script>