数组
1.概念
- 数组构成: 数组由一个或多个数组元素组成的,各元素之间使用逗号“,”分割。
- 数组元素:每个数组元素由“下标”和“值”构成。
下标:又称索引,以数字表示,默认从O开始依次递增,用于识别元素。
值:元素的内容,可以是任意类型的数据,如数值型、字符型、数组、对象等。
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 var mood = ['sad', , , ,'happy']; // 控制台输出mood:(5) ["sad", empty × 3, "happy"] </script>
注意:
在创建数组时,最后一个元素后的逗号可以存在,也可以省略。
直接法“”与Array()对象在创建数组时的区别在于,前者可以创建含有空存储位置的数组,而后者不可以。如:
var mood = ['sad', , , ,'happy'];
3.基本操作
Array的length属性
获取长度
其值为数组元素最大下标加1。
<script> var arr1 = [78, 88, 98]; var arr2 = ['a', , , , 'b', 'c']; console.log(arr1.length); // 输出结果为:3 console.log(arr2.length); // 输出结果为:6 </script>
数组arr2中没有值的数组元素会占用空的存储位置。因此,数组的下标依然会递增。从而arr2调用length属性最后的输出结果即为6。
修改长度
①若length的值大于数组中原来的元素个数,则没有值的数组元素会占用空存储位置。
②若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>
访问元素
数组元素访问方式:“数组名下标”。
<script> var arr = ['hello', 'JavaScript', 22.48, true]; console.log(arr[0]); console.log(arr[2]); console.log(arr); </script>
遍历元素
概念:所谓遍历数组就是依次访问数组中所有元素的操作。
利用下标遍历数组可以使用: for / for…in语句 / for…of语句
for (variable in object){...}
for…in中的variable指的是数组下标。
for…in中的object表示数组的变量名称。
除此之外,若object是一个对象,for…in还可以用于对象的遍历。
<div class="nav" id="navlist"></div> <script> var navlist = ['首页', '免费资源', '课程中心', 'IT学院', '学员故事', '线上学院', '技术社区']; var str = '<ul>'; for (var i in navlist) { str += '<li><a>' + navlist[i] + '</a></li>'; } str += '</ul>'; document.getElementById('navlist').innerHTML = str; </script>
效果如图
<script> var arr = [1, 2, 3]; for (var value of arr) { //for..of语句 console.log(value); } </script>
变量value:表示每次遍历时对应的数组元素的值。
变量arr:表示待遍历的数组。
结果:在控制台中依次输出1、2和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>
- 修改元素
修改元素与添加元素的使用相同,区别在于修改元素是为已含有值的元素重新赋值。
<script> var arr = ['a', 'b', 'c', 'd']; arr[2] = 123; arr[3] = 456; console.log(arr); // 输出结果:(4) ["a", "b", 123, 456] </script>
元素删除
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>
解构赋值
例如,若把数组[1,2.3]中的元素分别赋值为a、b和c,传统的做法是单独为变量声明和赋值。
<script> // 传统方式 var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2]; //解构赋值方式 [a,b,c]=[1,2,3]; </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>
【案例】javascript查找最大值与最小值
代码实现思路:假设法
①假设待查找数组的第一个
③在遍历数组时,判断当前元素是否大于max,若大于,修改max值。
④同理,在遍历数组时,判断当前元素是否小于min,若小于,修改min值。
<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>
4. 二维数组操作
创建
<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] = []; // 将当前元素设置为数组 arr[i][0] = i; // 为二维数组元素赋值 } </script>
若要为二维数组元素(如arr[i][0]
)赋值,首先要保证添加的元素(如arr[])已经
被创建为数组,否则程序会报“Uncaught TypeError…”错误。
【案例】javascript二维数组转置
二维数组的转置指的是将二维数组横向元素保存为纵向元素。
代码实现思路:
①找规律: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的创建与遍历,按②进行转置。
<script> 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>
5. 数组排序
冒泡排序
插入排序
插入排序: 是冒泡排序的优化,也是一种直观的简单排序算法。
实现原理: 通过构建有序数组元素的存储,对于未排序的数组元素,在已排序的数组中从最后一个元素向第一个元素遍历,找到相应位置并插入。
其中,待排序数组的第1个元素会被看作是一个有序的数组,从第2个至最后一个元素会被看作是一个无序数组。
6.常见数组方法
栈和队列方法
JavaScript中,除了前面讲解的添加与删除数组元素的方式外,还可以利用Array对象提供的方法,模拟栈和队列的操作。
- 在数组的末尾或开头添加数组的新元素。
- 在数组的末尾或开头删除数组元素。
push()和unshift()方法的返回值是新数组的长度。
pop()和shift()方法返回的是移出的数组元素。
检索方法
在开发中,若要检测给定的值是否是数组,或是查找指定的元素在数组中的位置。
表中除了Array.isArray()方法外,其余方法默认都是从指定数组索引的位置开始检索,且检索方式与运算符“===”相同,即只有全等时才会返回比较成功的结果。
- includes()方法的第1个参数表示待查找的值。
- includes()方法的第2个参数用于指定在数组中查找的下标。
·设置为大于数组长度时,数组不会被检索,直接返回false。
·设置为小于0的数时,则检索的索引位置等于数组长度加上指定的负数,若结果
仍是小于0的数,则检索整个数组。
【案例】includes()
用于确定数组中是否含有某个元素,含有返回true,否则返回falseo
【案例】Array.isArray()
用于确定传递的值是否是一个Array,是返回true,不是返回false。
<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)); // 输出结果:true </script>
【案例】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>
【案例】lastIndexOf()
返回指定元素在数组中的最后一个的索引,如果不存在则返回-1
<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>
数组转字符串
开发中若需要将数组转换为字符串时,则可以利用JavaScript提供的方法实现。
join()和toString()方法的相同点:
1.可将多维数组转为字符串,默认情况下使用逗号连接。
2.当数组元素为undefined、null或空数组时,对应的元素会被转换为空字符串
join()和toString()方法的不同点:
1.join()方法可以指定连接数组元素的符号。
<script> console.log(['a', 'b', '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>
其他方法
除了前面的几种常用方法外,JavaScript还提供了很多其他常用的数组方法。
例如,合并数组、数组浅拷贝、颠倒数组元素的顺序等。
- slice()和concat()方法在执行后返回一个新的数组,不会对原数组产生影响,其他方法在执行后皆对原数组产生影响。
- splice()方法的第1个参数的值等于或大于数组长度时,从数组末尾开始操作;当该值为负数时,则下标位置等于数组长度加上指定的负数,若其值仍为负数,则从数组的开头开始操作。
<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>
【案例】JavaScript猴子选大王**
游戏规则: 要求一群猴子排成一圈,按“1,2,…,n”依次编号。然后从第1只开始数,数到第m只,把它踢出圈,其后的猴子再从1开始数,数到第m只,再把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就是我们要找的大王。
代码实现思路:
①通过prompt()接收用户传递的猴子总数n和踢出的第m只猴子。
②利用数组保存所有猴子的编号(1~n)。
③设置一个变量i,记录每次参与游戏(报数)的猴子位置。
④通过while循环,只要猴子数组内元素个数大于1,就继续循环。
⑤在循环中判断当前猴子的位置i与m求余是否为0,若为零,删除该数组元素。
提示:通过出栈的方式取出猴子,如判断不为0,再将该元素入栈。
<script> var total = prompt('请输入猴子的总数'); var kick = prompt('踢出第几只猴子'); var monkey = []; for (var i = 1; i <= total; ++i) { // 创建猴子数组 monkey.push(i); } i = 0; // 记录每次参与游戏(报数)的猴子位置 while (monkey.length > 1) { // 在猴子数量大于1时进行循环 ++i; head = monkey.shift(); // 从monkey数组的开头,取出猴子 if (i % kick != 0) { // 判断是否踢出猴子,不踢则把该猴子添加到monkey数组的尾部 monkey.push(head); } } console.log('猴王编号:' + monkey[0]); </script>
【案例】JavaScript省份城市的三级联动 ***
代码实现思路:
创建HTML表单,实现省份、城市、区域的下拉列表。
创建数组保存省份城市区域的数据。
③编写函数createOption()用于创建指定下拉菜单的选项。
④选择省份后,显示对应城市菜单(利用onchange事件)。
⑤选择城市后,显示对应区域菜单(利用onchange事件)。
⑥修改省份后,更新城市和区域下拉菜单。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>省份城市的三级联动</title> </head> <body> <form> <select id="province"> <option value="-1">请选择</option> </select> <select id="city"></select> <select id="country"></select> </form> <script> // 省份数组 var provinceArr = ['上海', '江苏', '河北']; // 城市数组 var cityArr = [ ['上海市'], ['苏州市', '南京市', '扬州市'], ['石家庄', '秦皇岛', '张家口'] ]; // 区域数组 var countryArr = [ [ ['黄浦区', '静安区', '长宁区', '浦东区'] ], [ ['虎丘区', '吴中区', '相城区', '姑苏区', '吴江区'], ['玄武区', '秦淮区', '建邺区', '鼓楼区', '浦口区'], ['邗江区', '广陵区', '江都区'] ], [ ['长安区', '桥西区', '新华区', '井陉矿区'], ['海港区', '山海关区', '北戴河区', '抚宁区'], ['桥东区', '桥西区', '宣化区', '下花园区'] ] ]; // 第1步 function createOption(obj, data) { for (var i in data) { var op = new Option(data[i], i); // 创建下拉列表中的option选项 obj.options.add(op); // 将选项添加到下拉列表中 } } var province = document.getElementById('province'); createOption(province, provinceArr); // 第2步 var city = document.getElementById('city'); province.onchange = function() { city.options.length = 0; // 清空city下的原有<option> createOption(city, cityArr[province.value]); if (province.value >= 0) { city.onchange(); // 自动添加 城市对应区域 下拉列表 } else { country.options.length = 0; // 清空country下的原有<option> } }; // 第3步 var country = document.getElementById('country'); city.onchange = function() { country.options.length = 0; // 清空country下的所有原有<option> createOption(country, countryArr[province.value][city.value]); }; </script> </body> </html>