招式百出的数组(js)
数组的作用是:使用单独的变量名来存储一系列的值。数组是可以存储任意数据类型的数据。
1、创建
// 1、字面量 推荐 var arr = []; // 创建一个空数组 var arr = [1, 2, 3]; var arr = [1, 'ab', true, null, undefined, {}, [], function () { }, new Date()]; // 数组可以存储任意数据类型 console.log(arr); // 2、构造函数 var arr = new Array(); var arr = new Array(1, 2, 3); var arr = new Array(3); // [undefined, undefined, undefined] 这个3即数组的长度 var arr = new Array('3'); // [ "3" ] console.log(arr);
2、读、写、遍历
var arr = ['曹操', '刘备', '孙权']; // 读:数组[下标] console.log(arr[0]); console.log(arr[1]); console.log(arr[2]); console.log(arr[5]); // undefined 读取一个不存在的下标,返回undefined // 写:数组[下标] = 新值 arr[0] = '小美'; // [ "小美", "刘备", "孙权" ] arr[5] = '老王'; // [ "小美", "刘备", "孙权", undefined, undefined, "老王" ] console.log(arr); // ---------------------- // 遍历(不要用for-in) for (var i = 0; i < arr.length; i++) { console.log(arr[i]); }
3、数组的长度
数组长度,可读可写
var arr = ['刘备', '关羽', '张飞']; // 读 console.log(arr.length); // 3 // 写 arr.length = 5; // [ "刘备", "关羽", "张飞", undefined, undefined ] arr.length = 1; // [ "刘备" ] console.log(arr);
4、栈方法
1、数组头部或尾部添加或删除
var arr = ['刘备', '关羽', '张飞']; // 数组.push(参数); // 在数组的尾部添加,返回数组新的长度 var n = arr.push('张三', '隔壁老王'); console.log(arr); console.log(n); // 数组.unshift(参数); // 在数组的头部添加,返回数组新的长度 var n = arr.unshift('小美'); console.log(arr); console.log(n); // 数组.pop(); // 删除数组最后一项,返回被删除的项 var n = arr.pop(); console.log(arr); console.log(n); // 数组.shift(); // 删除数组的第一项,返回被删除的项 var n = arr.shift(); console.log(arr); console.log(n);
2、强大的splice方法,可以实现任意位置的添加、删除、替换
数组.splice(起始下标, 要删除的个数, 要添加的项...); 返回被删除的项组成的数组
var arr = ['刘备', '关羽', '张飞']; // 添加 var n = arr.splice(2, 0, '关平', '关兴'); console.log(arr); // [ "刘备", "关羽", "关平", "关兴", "张飞" ] console.log(n); // [] // 删除 var n = arr.splice(1, 1); console.log(arr); // [ "刘备", "张飞" ] console.log(n); // [ "关羽" ] // 替换 var n = arr.splice(1, 1, '小邓', '老王'); console.log(arr); // [ "刘备", "小邓", "老王", "张飞" ] console.log(n); // [ "关羽" ]
5、数组拼接
数组.concat(参数); 参数可以是数组,也可以是其它项。返回拼接以后的数组,不修改原数组
var arr1 = [1, 2, 3]; var arr2 = ['a', 'b', 'c']; // [1, 2, 3, 'a', 'b', 'c'] // var arr = arr1.concat(arr2, '小邓', '老王'); // console.log(arr1); // console.log(arr2); // console.log(arr); // -------------------- // 推荐用法 var arr = [].concat(arr1, arr2, '小邓', '老王'); console.log(arr);
数组.sort();
默认规则:按字符串排序,即便是数字,哪也是按字符串排序。会修改原数组
// 默认规则排序 var arr = [4, 6, 21, 9, 1, 7]; arr.sort(); console.log(arr); // [ 1, 21, 4, 6, 7, 9 ] // -------------------------- // 比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。 // 从小到大 var arr = [4, 6, 21, 9, 1, 7]; arr.sort(function (a, b) { return a - b; }); console.log(arr); // [ 1, 4, 6, 7, 9, 21 ] // --------------------- // 从大到小 var arr = [4, 6, 21, 9, 1, 7]; arr.sort(function (a, b) { return b - a; }) console.log(arr); // -------------------- // 随机排序 var arr = [1, 4, 6, 7, 9, 21]; arr.sort(function () { return 0.5 - Math.random(); }); console.log(arr);
根据对象的key值排序
// 按date进行降序排序,如果date一样,按DIU进行降序排序 var arr = [ { "date": "2018-08-01", "DIU": 1209, "country": "US" }, { "date": "2018-08-02", "DIU": 680, "country": "GB" }, { "date": "2018-08-01", "DIU": 2311, "country": "CN" }, { "date": "2018-08-02", "DIU": 879, "country": "US" }, { "date": "2018-08-03", "DIU": 1525, "country": "CN" }, { "date": "2018-08-02", "DIU": 1525, "country": "CN" } ]; arr.sort(function (a, b) { var t1 = Date.parse(a.date); // 随机取得数组项的date转成时间戳 var t2 = Date.parse(b.date); if (t1 === t2) { return b.DIU - a.DIU; } else { return t2 - t1; } }); console.log(arr); // console.log(Date.parse('2018-08-01')); // 1533081600000(将字符串转成时间戳)
按中文排
var arr = [ { name: '丽昕', num: 78 }, { name: '汤博', num: 38 }, { name: '卢博', num: 58 }, { name: '邓键', num: 97 }, { name: '继昂', num: 56 }, { name: '军安', num: 78 }, { name: '屈月', num: 98 }, { name: '秋萍', num: 79 } ]; // 按中文排 arr.sort(function (a, b) { return a.name.localeCompare(b.name, 'zh'); }); console.log(arr); // 按num排 arr.sort(function (a, b) { return a.num - b.num }); console.log(arr);
7、排序算法
-
选择排序
// 选择排序:从第一项起,每一项都和后面所有项依次比较,如果被比较项比当前项小,则两项交换位置。 // 每一轮,都找到一个最小的数,放到前面。 var arr = [5, 32, 2, 7, 45]; console.log(fn(arr)); // [2, 5, 7, 32, 45] function fn(arr) { for (var i = 0; i < arr.length - 1; i++) { for (var j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } console.log(arr.toString()); // 内部每一轮排序的结果 } return arr; }
-
冒泡排序
// 冒泡排序:从第一项起,比较相邻的两个元素,如果前一个比后一个大,则交换位置。第一轮的时候最后一个元素应该是最大的一个。每一轮最后一个元素已经是最大的了,所以最后一个元素下一轮不用比较。
var arr = [5, 32, 2, 7, 45]; console.log(fn(arr)); // [ 2, 5, 7, 32, 45 ] function fn(arr) { for (var i = 1; i < arr.length; i++) { for (var j = 0; j < arr.length - i; j++) { if (arr[j] > arr[j + 1]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } console.log(arr.toString()); } return arr; }
-
快速排序
// 快速排序:找到数组的第一项,把它删除。然后循环数组,如果比第一项小的,放在一个left数组中,如果比第一项大的,放在一个right的数组中,然后递归调用上面的方法。
var arr = [4, 6, 2, 6, 5, 8, 4, 7, 3]; console.log(fn(arr)); // [ 2, 3, 4, 4, 5, 6, 6, 7, 8 ] function fn(arr) { if (arr.length <= 1) { return arr; } var num = arr.shift(); // 删除数组第一项 var left = []; // 存储小于num的项 var right = []; // 存储大于等于num的项 for (var i = 0; i < arr.length; i++) { if (arr[i] < num) { left.push(arr[i]); } else { right.push(arr[i]); } } // console.log(left, num, right); return fn(left).concat(num, fn(right)); }
8、join
数组.join(参数)
将数组拼接成字符串。join()方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串。
9、reverse
// 数组.reverse(); 翻转 var arr = ['a', 'b', 'c']; arr.reverse(); console.log(arr); // [ "c", "b", "a" ] // ------------------- var str = '我爱你'; console.log(str.split('').reverse().join(''));
10、indexOf和lastIndexOf
// IE8及以下不支持 // 数组.indexOf(要查找的项, [查找的起始位置]); // 数组.lastIndexOf(要查找的项, [查找的起始位置]); // 返回查找的项在数组中的下标 var arr = [4, 3, 4, 2, 45, 43, 6, 3, 5]; console.log(arr.indexOf(3)); // 1 console.log(arr.indexOf(3, 2)); // 7 console.log(arr.indexOf('3')); // -1 console.log(arr.lastIndexOf(3)); // 7 // 数组去重 var arr = [2, 3, 4, 3, 3, 3]; console.log(fn(arr)); // [2,3,4] function fn(arr) { var newArr = []; // 仓库 for (var i = 0; i < arr.length; i++) { // 检查arr[i]在newArr中是否存在,如果不存在,则添加 if (newArr.indexOf(arr[i]) === -1) { newArr.push(arr[i]); } } return newArr; }
11、slice
// 数组.slice(起始下标, 结束下标); var arr = [4, 3, 4, 2, 45, 43, 6, 3, 5]; console.log(arr.slice()); // [ 4, 3, 4, 2, 45, 43, 6, 3, 5 ] console.log(arr.slice(2)); // [ 4, 2, 45, 43, 6, 3, 5 ] console.log(arr.slice(2, 6)); // [ 4, 2, 45, 43 ] console.log(arr.slice(2, -3)); // [ 4, 2, 45, 43 ] console.log(arr.slice(6, 2)); // []
12、Array.isArray
// 因为typeof不能判断数组 // Array.isArray(参数) IE8及以下不支持 如果参数是数组,返回true,否则返回fasle var arr = []; console.log(typeof arr); // object console.log(Array.isArray(arr)); // true console.log(Array.isArray({})); // false
13、迭代方法
IE8及以下不支持
-
forEach
// 数组.forEach(function (数组项, 下标, 数组本身) { }); // 作用:同for循环,用于遍历数组(没有返回值) var arr = ['刘备', '关羽', '张飞']; arr.forEach(function (item, index, array) { console.log(item, index, array); });
-
map
// 数组.map(function (数组项, 下标, 数组本身) { }); // 作用:循环数组,返回每次调用的结果组成的新数组 var arr = [3, 6, 4]; var n = arr.map(function (item, index) { // console.log(item, index); return item * 2; }); console.log(n); // [ 6, 12, 8 ]
-
filter
// 数组.filter(function (数组项, 下标, 数组本身) { }); // 作用:返回每次调用的结果为true的项组成的数组 var arr = [4, 45, 24, 4, 2]; var n = arr.filter(function (item, index) { // console.log(item, index); return item > 10 && item < 30; }); console.log(n);
-
every
// 数组.every(function (数组项, 下标, 数组本身) { }); // 作用:每一项调用的结果为true,则返回true var arr = [4, 45, 24, 4, 2]; var n = arr.every(function (item, index) { // console.log(item, index); return item > 0; }); console.log(n);
-
some
// 数组.some(function (数组项, 下标, 数组本身) { }); // 作用:只要有一项返回true,结果就是true var arr = [4, 45, 24, 4, 2]; var n = arr.some(function (item, index) { return item > 10; }); console.log(n);