数组
- 数组是一个引用列表(顺序,只有值,紧密,速度慢)
数组的创建
var array=[]; //创建空数组
var array=new Array(); //构造函数创建法
var arr=Array(); //不是创建方法,只是把字符串转化为数组类型,速度慢点儿
var arr=new Object([]); //对象数组,不建议使用,反正也还没用过
构造函数创建
- 构造函数实例化对象
var arr=new Array(1,2,3,4,5);
console.log(arr);
数组通过构造函数创建时,如果只有一个参数,并且参数是正整数,这个数就是数组的长度,而不作为数组的新元素;
如果是数字,但不是正整数,都会报错; 如果不是数字,则作为数组的第一个元素添加。
var arr=new Array(“3”);
console.log(arr); //[“3”]
var arr=new Array(9);
console.log(arr); //(9) [empty × 9] - 字符串转数组类型
var arr=Array(1,2,3,4,5,6);
console.log(arr);
var arr=Array(5);
console.log(arr); //(5) [empty × 5]
数组的结构
-
字面量创建数组
var arr0 = [1,2,3,4,5];两个","之间的那个是空元素。
var arr=[1,2,3,4,5];
arr是数组 1是索引值(下标) arr[1]元素(下标变量)。
console.log(arr[1]);
arr[1]=10; //可以修改下标变量的结果
console.log(arr[1]); -
数组的紧密性
arr[“5”]=10;
arr[7]=10; //如果下标值>数组长度-1,会创建空元素来补齐
console.log(arr); //(8) [1, 10, 3, 4, 5, 10, empty, 10]
另外用delete删除数组元素时,不会造成数组的自动收缩,紧密,数组的长度不会发生改变:
delete arr[2];
console.log(arr);//(5) [1, 2, empty, 4, 5] -
数组只有值存储,只能遍历数组获取值是否存在
for(var i=0;i<5;i++){
console.log(arr[i]);
}
console.log(arr); -
遍历内容较多时,当添加删除元素时,因为数组紧密性,速度变慢,尤其是在数组靠前位置插入和删除。
数组的长度 length
- console.log(arr.length); //表示当前数组得索引下标的最大值+1,因为从0开始
arr[arr.length]=10; //会在数组尾部添加一个值为10的新元素,数组长度亦+ 1。
每次添加元素后,长度会发生改变,length会变化的,因此上面这句不会修改最后一个元素,而是添加一个新元素;
arr[arr.lenght-1]; //代表最后一个元素; - 当添加不是索引数据(0开始),比如arr[-1],不会累计在长度中,而作为对象的key,value增加内容。
arr[-1]=10; //arr["-1"]=10;这样表示也行
console.log(arr); //[1, 2, 3, 4, 5, -1: 10]有对象的用法吧 - arr.length=8; //直接设置数组的长度,length>原有长度,则添加空元素补齐,使长度为length=8。
arr.length=10; - arr.length=arr.length-1; //如果长度比原来少一个,就会删除最尾部元素
arr.length–;
arr.length=0; //表示清空数组
绝对不能 arr=[]; //引用地址变化了,arr原来指向的内容变成孤儿对象了,相当于重新创建数组 - 数组长度—报错的情况
arr.length=-2; //数组的长度不能为负值,报错:Invalid array length
arr.length=“a”;
arr.length=true; //如果给的不是数值,会隐式转换为数值,如果值是NaN,就会报错
console.log(arr,arr.length);
判断是否是数组
判断是不是数组的几种方法:
ES6
console.log(Array.isArray(arr)); //true
ES5
console.log(Object.prototype.toString.call(arr)= = = “[object Array]”);
console.log(arr.constructor===Array); //常用方法,推荐使用
数组的方法
创建一个数组:var arr=[1,2,3];
1、push
- 在数组尾部添加一个or多个新元素,且返回数组的新长度。
console.log(arr.push(4,5)); //5 - push重构
function push(arr){
for(var i=1;i<arguments.length;i++){
arr[arr.length]=arguments[i];
}
return arr.length;
}
console.log(arr,push(arr,4,5)); //(5) [1, 2, 3, 4, 5]5
2、pop
- 删除数组尾部元素,且返回被删除的元素。
console.log(arr.pop()); //3 - pop重构
function pop(arr){
var value=arr[arr.length-1];
arr.length--;
return value;
}
console.log(pop(arr)); //3
3、unshift()
- 添加一个或多个新元素在数组的最前面,且返回数组的新长度。
console.log(arr,arr.unshift(-1,0)); //(5) [-1, 0, 1, 2, 3] 5 - unshift重构
function unshift(arr){
var len=arguments.length-1; //arguments[0]是arr参数
for(var i=arr.length-1;i>=0;i--){
arr[i+len]=arr[i]; //将arr的每个元素往后移添加的元素个数位
}
for(var i=1;i<arguments.length;i++){
arr[i-1]=arguments[i]; //将新添加的元素依次放入arr最前面
}
return arr.length;
}
console.log(arr,unshift(arr,-1,0)); //(5) [-1, 0, 1, 2, 3] 5
4、shift()
- 删除数组的第一个元素,且返回该元素。
console.log(arr.shift()); //-1 - shift重构
function shift(arr){
var value=arr[0];
for(var i=0;i<arr.length-1;i++){
arr[i]=arr[i+1];
}
arr.length--;
return value;
}
console.log(arr,shift(arr)); //(4) [0, 1, 2, 3] -1
5、concat()
- 复制
- 复制后给新数组添加新元素或新数组
- 连接,多个数组连接形成新数组
- 不改变原数组
var arr = [1, 2, 3, 4, 5];
var arr2=arr.concat(); //相当于复制
console.log(arr2,arr); //(5) [1, 2, 3, 4, 5] (5) [1, 2, 3, 4, 5]
var arr1=arr.concat(9,8,9,0,1); //复制后添加新元素到新数组的尾部
console.log(arr1,arr); //(10) [1, 2, 3, 4, 5, 9, 8, 9, 0, 1] (5) [1, 2, 3, 4, 5]
var arr3=arr.concat([11,22],[111,222]); //多个数组连接形成新数组赋值给arr3,arr不变
console.log(arr3,arr); //(9) [1, 2, 3, 4, 5, 11, 22, 111, 222] (5) [1, 2, 3, 4, 5]
- concat重构
// 我用的for in,不过注意,for in遍历的话会自动忽略空元素,
// 所以不要学我,还是老老实实用for循环吧
// 我以后也会用for的
function concat(arr){
var array=[];
for(var prop in arr){
array[prop]=arr[prop];
}
for(var i=1;i<arguments.length;i++){
if(arguments[i].constructor===Array){
for(var prop in arguments[i]){
array[array.length]=arguments[i][prop];
}
}else{
array[array.length]=arguments[i];
}
}
return array;
}
//for循环来实现
function concat(arr){
var array=[];
var index=0;
for(var i=0;i<arr.length;i++,index++){
array[index]=arr[i];
}
for(var j=1;j<arguments.length;j++,index++){
if(arguments[j].constructor===Array){
for(var k=0;k<arguments[j].length;k++,index++){
array[index]=arguments[j][k];
}
index--;//因为多加了一次,要判断k<arguments[j].length,index也跟着增加了
}else{
array[index]=arguments[j];
}
}
return array;
}
//for循环简化
function concat(arr){
var array=[]; //空数组的长度即array.length默认为0
for(var i=0;i<arr.length;i++){
array[array.length]=arr[i];
}
for(var j=1;j<arguments.length;j++){
if(arguments[j].constructor===Array){
for(var k=0;k<arguments[j].length;k++){
array[array.length]=arguments[j][k];
}
}else{
array[array.length]=arguments[j];
}
}
return array;
}
console.log(concat(arr,11,22,33),arr);//(8) [1, 2, 3, 4, 5, 11, 22, 33] (5) [1, 2, 3, 4, 5]
console.log(arr.concat(11,22,33));//(8) [1, 2, 3, 4, 5, 11, 22, 33]
console.log(concat(arr,11,arr,22,33,arr));// [1, 2, 3, 4, 5, 11, 22, 33, 1, 2, 3, 4, 5]
console.log(arr.concat(11,arr,22,33,arr));// [1, 2, 3, 4, 5, 11, 22, 33, 1, 2, 3, 4, 5]
console.log(arr.concat(11,22,33,arr));//(8) [1, 2, 3, 4, 5, 11, 22, 33]
var arr1=concat(arr,[10,11,12],0,[13,14,15]);//(12) [1, 2, 3, 4, 5, 10, 11, 12, 0, 13, 14, 15]
console.log(arr1);
6、join()
- 转化为字符串
- 用符号(参数)分割产生字符串
- 不改变原数组
console.log(arr.join("#"),arr);//1#2#3#4#5 (5) [1, 2, 3, 4, 5]
- join重构
function join(arr){
var str=""
for(var i=0;i<arr.length;i++){
if(arguments[1]==null) arguments[1]=","; //设置默认分隔符为","
str+= i==arr.length-1?arr[i]:arr[i]+arguments[1]+""; //+""要转化为字符串
}
return str;
}
console.log(join(arr,"#"));//1#2#3#4#5
7、splice(起始位置,删除元素个数,添加的新元素)
- 改变原数组
- 此起始位置为下标从0开始,包含此起始位置。
- 给数组中添加、删除、替换一个或多个元素,返回被删除元素组成的数组。
- 创建一个空数组
var arr1=arr.splice(); //没有被删元素,arr1=[ ]; - 传递数组arr的所有元素传递给新数组
var arr1=arr.splice(0); - 参数为负数意为 从后向前数
var arr1=arr.splice(-2); //从数组的倒数第二位开始截取到尾部。 - 删除、添加、替换元素
var arr = [1, 2, 3, 4, 5];
//从第二位开始删除2个元素。
var arr1=arr.splice(2,2);
console.log(arr1, arr); //(2) [3, 4] (3) [1, 2, 5]
//插入元素12,14在第二位。
console.log(arr.splice(2,0,12,14)); //(7) [1, 2, 12, 14, 3, 4, 5]
//替换元素,删除两位,并插入12,14
var arr1=arr.splice(2,2,12,14);
console.log(arr1,arr); //(2) [3, 4] (5) [1, 2, 12, 14, 5]
//如果删除的个数为非数值,则先转化为数值,再进行判断
var arr1=arr.splice(1,true,22);
console.log(arr1, arr); //[2] (5) [1, 22, 3, 4, 5]
//如果删除的个数为NaN,则不删除
var arr1=arr.splice(1,"d",22);
console.log(arr1, arr); //[] (6) [1, 22, 2, 3, 4, 5]
- splice重构
(备注:太复杂,没懂,先放一放)。
function splice(arr, start, count) {
var array = [];
start = Number(start);//以防传进来的参数非数值
count = Number(count);
if (isNaN(start)) return array;
if (start < 0) start += arr.length; //如果是负数,意为倒数第几位开始,为了方便,全部更改成正数模式
if(isNaN(count)) count=0; //如果删除的个数为NaN,则不删除
if (count < 0) count=0;
//把删除掉的元素拿出来放到array里面
for(var i=start,j=0;i<arr.length;i++,j++){
if(j<count) array.push(arr[i]);
arr[i]=arr[i+count];
}
for(var i=0;i<arguments.length-3;i++){
for(var j=arr.length-1;j>=start+i;j--){
arr[j+1]=arr[j];
}
}
for(var i=3;i<arguments.length;i++){
arr[start+i-3]=arguments[i];
}
//最后把多出来的元素去掉
for(var i=0;i<count;i++){
arr.length--;
}
return array;
}
var arr1=splice(arr,2,2,10,11,34);
console.log(arr1,arr); //(2) [3, 4] (6) [1, 2, 10, 11, 34, 5]
8、slice(起始位置,截止什么位置之前);
- 不改变原数组
- 此起始位置为下标从0开始,包含此起始位置;
- 截取复制,返回一个新数组。
- 复制一个新数组,没有引用关系
var ar1=arr.slice(); //默认从头复制到尾 - 其他用法
var arr = [1, 2, 3, 4, 5];
var arr1=arr.slice(1); //从第几项复制到尾部 (4) [2, 3, 4, 5]
var arr1=arr.slice(-2); //从倒数第二位复制到尾部 (2) [4, 5]
var arr1=arr.slice(2,3); //从第二位复制到第三位之前 [3]
var arr1=arr.slice(-3,-1); //从倒数第三位复制到倒数第一位之前 (2) [3, 4]
var arr1=arr.slice(2,-1); //从第二位复制到倒数第一位之前 (2) [3, 4]
console.log(arr1);
- slice重构
function slice(arr, start, end) {
start = Number(start);
end = Number(end);
if (isNaN(start)) start = 0;
if (isNaN(end)) end = arr.length;
if (start < 0) start=start+arr.length;
if (end < 0) end=end+arr.length;
var array=[];
for(var i=start,j=0;i<end;i++,j++){
array[j]=arr[i];
}
return array;
}
console.log(slice(arr,2,arr.length-1)); //(2) [3, 4]
9、indexOf
-
arr.lastIndexOf(要查找的元素,从第几位开始查找包含此位);
查找元素在数组中的下标,如果没有查找到,则返回-1。
var arr=[1,2,2,4,3,4,5,4,2,6,2,7];
console.log(arr.indexOf(4)); //3 所查找的4,第一次出现下标为3
console.log(arr.indexOf(4,4)); //5 查找4,从第4位开始查找(注意,下标从0开始)
console.log(arr.indexOf(14,4)); //-1 没找到14 -
arr.lastIndexOf(要查找的元素,从第几位开始查找包含此位);
从后向前查找。
lastIndexOf() 方法可返回一个指定的元素在数组中最后出现的位置,从该字符串的后面向前查找。如果要检索的元素没有出现,则该方法返回 -1。
console.log(arr.lastIndexOf(6)); //9
console.log(arr.lastIndexOf(6,3)); //-1 从下标3开始往前查找,未查找到6 -
查找元素出现时的所有下标
原理解释:
~ arr.indexOf(2); //比如说找2,没找到返回-1,只有~(-1)=0,其他都不是0;
所以 if(~arr.indexOf(value)) 意为当不是-1即找到value值时进入条件;
if(!~arr.indexOf(value)) 意为当没找到值时进入条件。
var arr=[1,2,2,4,3,4,2,,5,4,2,6,2,7];
var index=-1;
while(~(index=arr.indexOf(2,index+1))){
//当找到进入条件,直到查找结束;
//找到时,把下标赋值给index,下次循环开始,直接跳到被找到下标的下个下标,避免了重复打印
//没找到返回-1,而~(-1)=0,不进入条件。
console.log(index)
}
//用for循环解释一下
for(var i=0;i<arr.length;i++){
if(~(arr.indexOf(2,i))) {
console.log(arr.indexOf(2,i));
i=arr.indexOf(2,i);
}
}
- 数组去重
因为数组的严密性,每次删除一个元素,就得动很多其他元素;
因此可以创建一个新数组,将符合要求的数给新数组,再重新给原数组赋值;
如果没有写在函数中,那么不要忘了把新数组最后置null,给垃圾回收掉。
var arr=[1,2,2,3,4,3,4,5,4,2,6,2,7,8];
function nonRep(arr){
var arr1=[];
for(var i=0;i<arr.length;i++){
if(arr1.indexOf(arr[i])<0) arr1.push(arr[i]); //将arr[i]的值与arr1里的比较
}
arr=arr1.splice(0);
//arr1=null; //函数执行完毕局部变量arr1会被销毁,无须再写
return arr;
}
console.log(nonRep(arr));//(8) [1, 2, 3, 4, 5, 6, 7, 8]
不用indexOf的话,方法如下:
var arr=[1,2,2,4,3,4,5,4,2,6,2,7];
var arr1=[];
for(var i=0;i<arr.length;i++){
var bool=false;
for(var j=0;j<arr1.length;j++){
if(arr[i]===arr1[j]){
bool=true;
break;
}
}
if(!bool){
arr1.push(arr[i]);
}
}
arr=arr1.splice(0);
arr1=null; //没有写在函数中,不会自动被销毁,所以就手动回收呗
console.log(arr); //(7) [1, 2, 4, 3, 5, 6, 7]
数组的遍历
1、说到数组的遍历,先说说 for in 和 for循环:
for in 循环可以把数组的可枚举属性遍历到,但不能遍历到数组的空元素。null可以遍历到,因为null不属于空元素。
for循环可以遍历到空元素,但是空元素会被打印为undefined。
for与for in的比较
var arr1=[11,22,33,44,,66];
console.log(arr1);//(6) [11, 22, 33, 44, empty, 66] 打印,空元素被打印成empty
//for in
for(var prop in arr1){
console.log(arr1[prop]);//遍历不到空元素
}
//for
for(var i=0;i<arr1.length;i++){
console.log(arr1[i]);//空元素会被打印为undefined
}
2、数组的去重遍历
跟之前介绍的一样,delete删除的元素会被替换成empty,数组长度不变。
var arr=[1,1,2,2,4,3,4,5,4,2,6,2,7];
//先将重复的元素删除掉,注意数组长度不变,删除的元素会用empty占位
for(var i=0;i<arr.length;i++){
if(arr.indexOf(arr[i],i+1)>-1) delete arr[i];//保留重复出现元素值的最后一个
// if(arr.lastIndexOf(arr[i],i-1)>-1) delete arr[i]; /*保留重复出现元素值的第一个*/
}
//for in会自动忽略空元素
var arr1=[];
for(var prop in arr){
arr1.push(arr[prop]);
}
arr=arr1.splice(0);
arr1=null;
console.log(arr); //(7) [1, 3, 5, 4, 6, 2, 7]
3、数组还有两个方法常用来只做遍历。
10、forEach() 遍历
- 不遍历空元素,也不遍历属性;
- 匿名函数,无法阻止它在循环中中断循环跳出;
var arr = [2, 4, 6, 8, 10, , 12, 14, 16, 18, 20];
arr.forEach(function (item, index, a) {
if(index===2) return; //遍历不会中断,但是会跳过下标为2的元素
console.log(item, index, a); ////依次为元素、索引、数组;此处遍历,共打印arr.length次;若元素值为空,则不会遍历到此元素,直接跳过此元素
});
- 不返回任何值;
- forEach重构
function forEach(arr,fn){
for(var i=0;i<arr.length;i++){
if(arr[i]===undefined) continue; //空元素不遍历
fn(arr[i],i,arr);
}
}
// 桥接模式
forEach(arr,function(item,index,a){
console.log(item,index,a);
});
11、map() 遍历
- 将回调函数return的结果,返回到新数组中;
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。 - 不会对空数组进行检测(但空元素依然存在)。
- 不改变原数组。
var arr = [1,2,,3];
var a=arr.map(function(item,index,a){
// console.log(item,index,a); //与forEach打印结果并无二致
return item+100;
});
console.log(a,arr); //(4) [101, 102, empty, 103] (4) [1, 2, empty, 3]
- map重构
function map(arr,fn){
var array=[];
for(var i=0;i<arr.length;i++){
if(arr[i]===undefined) continue; //不检测空元素
array[i]=fn(arr[i],i,arr);
}
return array; //返回新数组
}
var a=map(arr,function(item,index,a){
return item+1000;
});
console.log(a,arr); //(4) [1001, 1002, empty, 1003] (4) [1, 2, empty, 3]
12、some()
遍历数组,查找是否满足条件,若满足条件,就直接跳出遍历,返回true;若不满足条件,返回false。
var arr=[1,2,3,4,5];
var bool = arr.some(function (item, index, a) {
return item > 4;
});
console.log(bool); //true
- some重构
function some(arr,fn){
for(var i=0;i<arr.length;i++){
if(arr[i]===undefined) continue; //不检测空元素
if(fn(arr[i],i,arr)) return true;
}
return false;
}
var bool=some(arr,function(item,index,a){
return item>10;
});
console.log(bool); //false
13、every()
遍历数组,判断每一个是否都满足条件,如果有一个不满足,直接返回false。
var arr=[1,2,3,4,5];
var bool=arr.every(function(item,index,arr){
//参数index,arr可以省略,等用到的时候再写也行
return item>0;
});
console.log(bool); //true
- every重构
function every(arr,fn){
for(var i=0;i<arr.length;i++){
if(arr[i]===undefined) continue; //不检测空元素
if(!fn(arr[i],i,arr)) return false; //如果有一个元素不满足条件而返回false,则!false==true,就会执行return false语句,直接返回false
}
return true;
}
var bool=every(arr,function(item){
return item>4;
});
console.log(bool); //false
(注意:有个小案例,全选问题,请看下面 "非数组列表转化为数组"中的示例)
14、arr.fill() 填充元素
fill填充,只适用于构造函数创建的数组中
var arr1=new Array(3);
console.log(arr1.fill(100));//(3) [100, 100, 100]
15、filter() 筛选
- 筛选出符合条件的
- 返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。
- 不改变原数组
var i = 0;
var arr = [1, 2,, 2, 4, 3, 4, 5, 4, 2, 6, 2, 7];
var arr1 = arr.filter(function (item, index, a) {
console.log(item,index,a); //不检测空元素,跳过空元素
if (item === 2)
i++;
return item > 2; //返回满足条件的所有元素
});
console.log(arr1, i, arr.length,arr); //(7) [4, 3, 4, 5, 4, 6, 7] 4 13 (13) [1, 2, empty, 2, 4, 3, 4, 5, 4, 2, 6, 2, 7]
- filter重构
var arr = [1, 2,, 2, 4, 3, 4, 5, 4, 2, 6, 2, 7];
function filter(arr,fn){
var array=[];
for(var i=0;i<arr.length;i++){
if(fn(arr[i],i,arr)) array[array.length]=arr[i];
}
return array;
}
var arr1=filter(arr,function(item,index,a){
return item>4;
});
console.log(arr1); //(3) [5, 6, 7]
- 应用示例
var data = [ //对象型数组(复杂型数组)
{ id: 1001, icon: "img/1.png", name: "餐饮0", num: 1, price: 10 },
{ id: 1002, icon: "img/2.png", name: "餐饮1", num: 1, price: 20 },
{ id: 1003, icon: "img/3.png", name: "餐饮2", num: 1, price: 30 },
{ id: 1004, icon: "img/4.png", name: "餐饮3", num: 1, price: 40 },
{ id: 1005, icon: "img/5.png", name: "餐饮4", num: 1, price: 50 },
{ id: 1006, icon: "img/6.png", name: "餐饮5", num: 1, price: 60 },
{ id: 1007, icon: "img/7.png", name: "餐饮6", num: 1, price: 70 },
{ id: 1008, icon: "img/8.png", name: "餐饮7", num: 1, price: 80 },
{ id: 1009, icon: "img/9.png", name: "餐饮8", num: 1, price: 90 },
{ id: 1010, icon: "img/10.png", name: "餐饮9", num: 1, price: 100 }
];
var arr1=data.filter(function(item,index,arr){
return item.id===1006;
})
console.log(arr1); //返回数组[{…}],内容是 {id: 1006, icon: "img/6.png", name: "餐饮5", num: 1, price: 60}
16、reduce() 归并
- 简介:
arr.reduce(function(上次归并值,本次遍历的元素,索引值,数组),初始化值);
如果没有设置初始化值,上次归并值初始值为数组的第0项,本次遍历将从下标1开始;
如果设置了初始化值,上次归并值初始值就是初始化值,本次遍历将从下标0开始。
var arr=[1,2,3,4,5];
var sum=arr.reduce(function(value,item,index,arr){
console.log(value,item,index); //每次计算完成后三者的值
return value+item; //返回到value,value是上次归并值
},100);
console.log(sum); //可以计算最后return的值 115
- reduc重构
var arr=[1,2,3,4,5];
function reduce(arr,fn,initValue){//initValue 代表初始值
var start=0; //代表遍历开始下标
//如果没有设置初始值,上次归并值为arr[0],本次遍历从arr[1]的下标1开始
if(initValue===undefined){
initValue=arr[0];
start++;
}
//否则,上次归并值为初始值,遍历从下标0开始,本次归并的结果给initValue
for(var i=start;i<arr.length;i++){
initValue=fn(initValue,arr[i],i,arr);
}
return initValue;
}
var sum=reduce(arr,function(value,item,index,a){
return value+item;
},100);
console.log(sum); //115
- reduce常用应用:
1、求总价;
2、把很多符合条件的结果归并起来;
3、reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值,就如上面那段程序所实现的功能;
4、reduce() 可以作为一个高阶函数,用于函数的 compose; - 注意: reduce() 对于空数组是不会执行回调函数的(不检测空元素,跳过空元素)。
- 应用示例
var data = [
{ id: 1001, icon: "img/1.png", name: "餐饮0", num: 1, price: 10 },
{ id: 1002, icon: "img/2.png", name: "餐饮1", num: 1, price: 20 },
{ id: 1003, icon: "img/3.png", name: "餐饮2", num: 1, price: 30 },
{ id: 1004, icon: "img/4.png", name: "餐饮3", num: 1, price: 40 },
{ id: 1005, icon: "img/5.png", name: "餐饮4", num: 1, price: 50 },
{ id: 100, icon: "img/6.png", name: "餐饮5", num: 1, price: 60 },
{ id: 1007, icon: "img/7.png", name: "餐饮6", num: 1, price: 70 },
{ id: 1008, icon: "img/8.png", name: "餐饮7", num: 1, price: 80 },
{ id: 1009, icon: "img/9.png", name: "餐饮8", num: 1, price: 90 },
{ id: 1010, icon: "img/10.png", name: "餐饮9", num: 1, price: 100 }
];
1、模拟购物车计算价格总和
//给每个元素增加一个selected属性;
//通过Math.random() < 0.5来确定selected是否为选中状态;
//然后固定数量num不超过10;
//把该商品的总价格算出来;
data.forEach(function (item) {
item.selected = Math.random() < 0.5;
item.num = parseInt(Math.random() * 5 + 5);
item.total = item.num * item.price;
// console.log(item.selected,item.num,item.total); //自己打印试试
});
//将所有被选中的商品价格总值加起来,计算总总价格后给value
var sum = data.reduce(function (value, item) {
return item.selected ? value + item.total : value;
}, 0);
console.log(sum);
2、如果找到返回该id===1006的,否则返回归并值
// var item = data.reduce(function (value, item) {
// return item.id == 1006 ? item : value;
// }, null);
// console.log(item); //没找到,返回null
17、reverse()倒序
- 倒序,翻转数组,不排序,改变原数组,并返回返回原数组。
var arr=[1,4,6,2,3,8,7,6,5,3,9];
console.log(arr.reverse(),arr); //结果都是(11) [9, 3, 5, 6, 7, 8, 3, 2, 6, 4, 1]
//不排序,因此与数组元素值无关
var arr=["a","b","c","d"];
console.log(arr.reverse()); //(4) ["d", "c", "b", "a"]
- reverse重构
1、第一种方法
//重构思想:从中间对半劈开,以temp为介质,把前后元素位置交换
var arr=[1,4,,"c","d",3,9];
function reverse(arr){
var len=parseInt(arr.length/2); //交换次数
for(var i=0;i<len;i++){
var temp=arr[arr.length-1-i];
arr[arr.length-1-i]=arr[i];
arr[i]=temp;
}
return arr;
}
console.log(reverse(arr)); //(7) [9, 3, "d", "c", undefined, 4, 1]
2、重构第二种方法
//重构思路:新创建一个数组arr1,然后把原数组arr的值颠倒到新数组arr1里;
//最后再把新数组arr1的元素重新赋值给原数组arr,函数执行完毕,局部变量arr1销毁
var arr=[0,4,,"c","d",3,0];
function reverse1(arr){
var array=[];
var index=0;
for(var i=arr.length-1;i>=0;i--){
array[index++]=arr[i];
}
arr=array.splice(0);
return arr;
}
console.log(reverse1(arr)); //(7) [0, 3, "d", "c", undefined, 4, 0]
18、sort() 排序(正序(默认)/倒序/乱序)
1、直接排序,只能按元素值的第一个数字进行排序
var arr=[1,4,6,3,9,10,100];
arr.sort();
console.log(arr); //(7) [1, 10, 100, 3, 4, 6, 9] 有问题哦
2、正序排列
arr.sort(function(a,b){
return a-b;
})
console.log(arr); //(7) [1, 3, 4, 6, 9, 10, 100]
3、倒序排列
arr.sort(function(a,b){
return b-a;
})
console.log(arr); //(7) [100, 10, 9, 6, 4, 3, 1]
4、乱序排列,每次排列结果不一样
var arr=[];
for(var i=0;i<100;i++){
arr.push(i); //给arr添加0~99的元素
}
//乱序排列
var i=-1;
arr.sort(function(){
return Math.random()-0.5; //乱的比较彻底
})
console.log(arr); //0~99的数字乱序打印出来
19、flatMap
- 遍历,将二维数组扁平化;
- 不改变原数组;
- 返回一个新数组。
var arr1=[[1,2,0,,3],[4,5,6],7,8,"s",,9];
var arr2=arr1.flatMap(function(item,index,a){//用arr2接收返回的新数组
//console.log(item,index); //打印一下看看
return item;
});
console.log(arr2,arr1);
//arr2: [1, 2, 0, 3, 4, 5, 6, 7, 8, "s", 9]
//arr1:[Array(5), Array(3), 7, 8, "s", empty, 9]
三种常见排序
- 冒泡排序、选择排序、快速排序
1、冒泡
/*
冒泡排序:
1、从后向前循环;
2、内部从前向后循环到外层变量;
3、判断前值是否大于后值,若大于,则交换。
*/
var arr=[1,4,2,2,3,10];
function bubblingSort(arr){
var len=arr.length;
while(len>0){
for(var i=0;i<len;i++){
if(arr[i]>arr[i+1]){
var temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
len--;
}
}
bubblingSort(arr);
console.log(arr); //(6) [1, 2, 2, 3, 4, 10]
2、选择排序
/*
选择排序
思路:先找出最小或者最大的索引值,然后用当前的下标的元素与这个最小的元素交换。
1、遍历数组;
2、设置最小的索引值为当前的索引值;
3、从当前的下一项开始遍历到数组的尾部;
4、判断所有遍历的值中最小的值得索引值;
5、交换当前值和最小索引值的元素。
*/
function indexSort(arr){
var minIndex;
var len=arr.length;
for(var i=0;i<len;i++){
minIndex=i;
for(var j=i+1;j<len;j++){
minIndex=arr[minIndex]<arr[j]?minIndex:j;
}
var temp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
var arr=[1,4,2,2,3,10];
indexSort(arr);
console.log(arr); //(6) [1, 2, 2, 3, 4, 10]
3、快速排序
/*
快排(快速排序)
1、删除数组中间的元素,并且,将这个元素返回一个变量;
2、创建两个空数组,一个是left,一个是right,遍历这个数组,
将小于中间元素的数据存入left,大于中间元素的数据存入right;
3、将left数组递归与中间元素和right数组递归的结果合并返回;
4、在函数最顶部,一定要写数组长度小于等于1,返回该数组。
注意:要重新赋值给元素组替换。
*/
function quickSort(arr){
if(arr.length<=1) return arr;
var left=[];
var right=[];
//因为splice返回的是被删除元素组成的数组,哪怕只有一个元素,也得把它提取出来
var item=arr.splice(parseInt(arr.length/2),1)[0];
for(var i=0;i<arr.length;i++){
if(arr[i]<item) left.push(arr[i]);
else right.push(arr[i]);
}
var arr1=quickSort(left).concat(item,quickSort(right)); //递归
return arr1;
}
var arr=[1,4,2,2,3,10];
arr=quickSort(arr); //重新赋值替换原数组
console.log(arr); //(6) [1, 2, 2, 3, 4, 10]
非数组列表转化为数组
- 几种不同方法:
var inputs=document.getElementsByTagName("input");
console.log(inputs); //HTMLCollection(10)
把他转换成数组的几种方法:
ES6
var list=Array.from(inputs);
console.log(list); //Array(10)
ES5
var list=Array.prototype.slice.call(inputs);
var list=[].slice.call(inputs);
var list=Array.prototype.concat.apply([],inputs);
var list=[].concat.apply([],inputs);
- 示例:
<p>
功能介绍:
按第一个全选按钮,所有选框同时选中或解除选中;
单按下面的选框,只要有未选中的,全选按钮就为未选中状态。
</p>
<ul>
<li><input type="checkbox">全选</li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
</ul>
var inputs = document.getElementsByTagName("input");
var arr = Array.from(inputs); //转换成数组
for(var i=0;i<arr.length;i++){
arr[i].onclick=clickHandler; //给每个input添加点击事件
}
function clickHandler(){
var self=this;
if(arr.indexOf(this)===0){//如果按第一个全选按钮
arr.forEach(function(item,index){
if(index===0) return; //不检测第一个全选按钮
//用self而非this,是因为forEach中的this被重新指向到window(所有的回调函数中也有这一特点),万恶的this
item.checked=self.checked;
//其余选框的状态跟随全选按钮的状态
})
}else{//如果按其他普通按钮
arr[0].checked=arr.slice(1).every(function(item){
return item.checked;
//如果所有的普通按钮都被选中了,都为true,那么全选按钮为选中状态;
//反之,只要有一个选框未选中为false,全选按钮就为未选中false
})
}
}
复杂型数组
二维数组和多维数组
- 行列唯一对应值(完成格状物的操作)。
//二维数组
var arr0 = [];//先定义一个数组
for (var i = 0; i < 10; i++) {
arr0[i] = [];//第二层数组
for (var j = 0; j < 20; j++) {
arr0[i][j] = i * 10 + j;//二维数组赋值
}
}
console.log(arr0);//行列有唯一对应值
- 二维数组扁平化,flatMap,不检测空元素
1、当数组元素类型统一
var arr=[[1,2,3],[4,5,6],7,8,9];
var arr1=arr.flatMap(function(item,index,a){
return item;
})
console.log(arr1); //(9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
2、当数组元素类型不统一
var arr=[[1,2,0,,3],[4,5,6],7,8,"s",,9];
//用flatMap将上面的数组扁平化结果为[1, 2, 0, 3, 4, 5, 6, 7, 8, "s", 9];
对象型数组
//对象型数组
var kk={ id: 1005, icon: "img/5.png", name: "餐饮4", num: 1, price: 50 };
var data = [//定义对象数组,每个元素都是一个对象
{ id: 1001, icon: "img/1.png", name: "餐饮0", num: 1, price: 10 },
{ id: 1002, icon: "img/2.png", name: "餐饮1", num: 1, price: 20 },
{ id: 1003, icon: "img/3.png", name: "餐饮2", num: 1, price: 30 },
{ id: 1004, icon: "img/4.png", name: "餐饮3", num: 1, price: 40 },
kk,
{ id: 1006, icon: "img/6.png", name: "餐饮5", num: 1, price: 60 },
{ id: 1007, icon: "img/7.png", name: "餐饮6", num: 1, price: 70 },
{ id: 1008, icon: "img/8.png", name: "餐饮7", num: 1, price: 80 },
{ id: 1009, icon: "img/9.png", name: "餐饮8", num: 1, price: 90 },
{ id: 1010, icon: "img/10.png", name: "餐饮9", num: 1, price: 100 }
];
//错误用法
var obj={ id: 1005, icon: "img/5.png", name: "餐饮4", num: 1, price: 50 };
console.log(data.indexOf(obj));//-1 不能找到对象元素的索引,因为这个的引用地址,与上面的引用地址是不一样的
//正确用法
console.log(data.indexOf(kk));//4
来源:CSDN
作者:weixin_43297321
链接:https://blog.csdn.net/weixin_43297321/article/details/104175289