数组详解
给数组开头增加新内容的方法:
unshift;
ary.[0]=xxx;
ary.splice(0,0,X);
ary.slice();
//删除数组第一项:
shift;
splice(0,1);
//给数组末尾增加:
push;
splice(ary.length,0,x)
//数组克隆;
slice();
contact();
数组的基础结构
数组是对象类型
属性名是数字
类数组
类似数组 但不是数组(以下是类数组)
- 通过getElementsByTagName等获取的元素集合
- 函数中的实参集合argument
(记忆数组要按以下几个维度1、方法的意义2、方法的形参3、方法的返回值4、通过此方法,原来数组是否发生改变)
var ary=[12,34,5];
ary.push('sd');
增加
1、push
- 向数组末尾增加新内容
- 参数:一个到多个,任何数据都可以,用逗号隔开
- 返回值:新增数组后的长度
- 原有的数组变了
2、unshift - 向数组开头增加新内容
- 参数:一个到多个,任何数据都可以,用逗号隔开
- 返回值:新增数组后的长度
- 其余同push
3、把数组当做一个普通的对象,使用对象键值对操作,给其设置新的属性 ary[length]=xxx; - 向数组末尾添加一个新内容
删除
1、pop
- 功能:删除数组最后一项
- 参数:无
- 返回值:被删除的那一项
- 原有数组改变了
2、shift
- 删除数组第一项(后面每一项索引都要向前进一位)
- 参数:无
- 返回值:被删除那一项
- 原有数组改变
3、delete 把数组当做普通的对象操作 delete ary[索引]
- 删除指定那一项,其余的索引不会改变,数组的length也不变
4、ary.length–;删除数组最后一项
5、splice: 数组中内置的方法,可以实现数组的增加、修改、删除
splice实现删除
- splice(n,m):从索引n开始删除m个 (m不写是删除到末尾,都不写是不删除)ary.splice(0)全部删除
- 返回值:被删除的内容(以一个新数组来保存被删除的内容)
- 原有数组改变
splice实现修改
- splice(n,m,x):用x代替删除的内容
- splice 实现增加
- splice(n,0,x);在修改的基础上,一项都不删除,将x放在n的前面
- splice(0,0,x) 向数组开头增加一个
- splice(ary.length,0,x) 向数组末尾增加一项
- splice(0,1);删除数组第一项
- splice(ary.length-1,1) 删除数组最后一项
- splice(n,0,x);在修改的基础上,一项都不删除,将x放在n的前面
数组查询
1、slice:数组查询
- 参数:slice(n,m)从索引n开始找到索引m处(不包含m)
- 返回值:把找到的部分以一个新数组返回
- 原来数组不改变
- slice(n);从n开始找到末尾
- slice(0)/slice();数组克隆,克隆一份和原来一模一样的新数组;
- slice支持负数,解析时按照:总长度+负数索引 来处理
将两个数组进行拼接
concat
- 将多个数组拼接在一起
- 参数:要拼接的内容放在原数组后面
- 返回:拼接后新数组
- 原有数组不变
- concat(),什么都没有拼接,相当于把原有的数组克隆;
数组克隆后出现的是一个新数组,与原有数组不相同,拷贝一份
把数组转化为字符串
1、toString
- 实现把数组转化为字符串,一逗号分隔
- 参数:无参数
- 返回:转换后的字符串
- 原有数组不变
- 2、join
- 把数组按照指定的分隔符转换为字符串,和字符串中的split相对应
- 参数:指定连接符
- 返回值:转化后的字符串
- 原有数组不变
eval:把字符串变为JS表达式执行
var total=eval(ary.join(‘+’)); 可实现数组求和;(一般项目中尽量不要用eval,性能较差)
实现数组中每一项的排序和排列
1、reverse
- 把数组倒过来排列
- 参数 :无
- 返回值:排序后的数组
- 原有数组改变
2、sort
- 实现数组排序
- 参数:无或回调函数;
- 返回值:排序后的
- 原有数组改变
不传参的情况下,只能识别10以内的数字,多位数只识别第一位
ary.sort(function(a,b){
return a-b; //升序 a-b>0,a和b交换位置
return b-a;//降序
})
遍历数组中每一项的方法( 以下方法在IE6-8都不支持)
方法名 | 是否操作原数组 | 方法返回结果 | 回调函数返回结果 |
filter(过滤) | 否 | 过滤后的新数组 | true/false,若true则放到新数组中 |
map(映射) | 否 | 新数组 | return后的值 |
find | 否 | 返回找到的那一项,没有返回-1 | 返回true表示找到了,并停止 |
some | 否 | boolean | 找true,找不到返回false |
every | 否 | boolean | 找false,找不到返回true |
reduce | 否 | 累积后的结果 | 返回的是下一次的prev |
遍历数组或类数组、字符串每一项
for …of
let arr = [2, 4, 1, 3];
for(let val of arr){
console.log(val);//2,4,1,3
}
find
用于找出
第一个符合条件
的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员
。如果没有
符合条件的成员,则返回undefined
。
let arr = [2, 4, 1, 3];
res=arr.find((item)=>{
return item>1;
})
console.log(res);//2
findIndex
find方法非常类似,返回
第一个符合条件
的数组成员的位置
,如果所有成员都不符合条件,则返回-1
。
let arr = [2, 4, 1, 3];
res=arr.find((item)=>{
return item>1;
})
console.log(res);//0=>2的索引
//find,findIndex都可以接受第二个参数,用来绑定回调函数的this对象
forEach(不支持return)
对数组中的每一项运行给定函数,没有返回值
let arr = [2, 4, 1, 3];
arr.forEach(function (item, index) {
console.log(item);//2, 4, 1, 3
})
some:
对数组中的每一项运行给定函数,只要一个条件成立,则返回true,条件都不成立才返回false;
let arr = [2, 4, 1, 3];
res = arr.some((item, index) => {
return item > 3;
})
console.log(res);//true
对数组中的每一项运行给定函数,条件都成立才返回true,只要有一个不成立,则返回false
let arr = [2, 4, 1, 3];
let res4 = arr.every((item, index) => {
return item > 3;
})
console.log(res4);//false
map():(映射)
对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
let ary = [2, 4, 1, 3];
let res1=ary.map((item,index)=>{
return item*2;
});
console.log(res1);//[4,8,2,6]
两个归并数组的方法:reduce,reduceRight
reduce:
对数组中的每一项运行给定函数,计算数组每一项的累积值 prev:累积项,next当前项
4个参数:[pre,next,index,ary] index:next的索引,ary:原数组
let arr = [2, 4, 1, 3];
//实现每一项成员的累加
let res5 = arr.reduce((prev, next) => {//当没有第二个参数时,第一次prev是第一项,next是第二项,然后将他们的和赋值给prev,然后next值会等于第三项,prev就等于累加项,以此类推
return prev + next;
},0)//0是给prev设置的默认值,可不加,当prev有默认值时,next从第一项开始
console.log(res5);//10
eg2:
let arr1= [{price: 10, count: 2}, {price: 3, count: 6}];//求总金额
let res6 = arr.reduce((prev,next => {
return prev+next.price+next.count;
}), 0);//0是prev的默认值,此时next第一次就等于数组第一项;
console.log(res6);
reduceRight
使用 reduce()还是 reduceRight(),主要取决于要从哪头开始遍历数组。除此之外,它们完全相同。
filter (过滤)
对数组中的每一项运行给定函数, 筛选掉不符合条件的,返回匹配条件的 (返回的是一个新数组)
let res2 = ary2.filter((item,index)=>{ //删除功能时用的多
return item<4
})
console.log(res2);//[2,1,3]
数组方法,验证数组中是否包含某一项
indexOf/lastIndexOf :获取当前项在数组中第一次或最后一次出现位置的索引
- 数组中这两个方法在IE6-8下不兼容
- 字符串中的这两个方法兼容所有的浏览器
- 如果当前数组中没有这一项,则返回-1;
数组去重
方法一:
遍历数组
将数组的每一项和上一项比较,如果相同,则删除这一项(for)
方法二
遍历数组
每次将数组的某一项和剩下的比较indexOf,如果相同,就删除该项,那么最后留下来的就没有重复项了;
var ary=[2,7,8,9,45,8,78,4,2,7];
for(var i;i<ary.length;i++){
var ary2=ary[i];
ary3=ary.splice(i+1);
if (ary3.indexOf(ary2)>-1){
ary.splice(i,1);
i--;
}
}
console.log(ary);
方式三(键值对的方式)
遍历数组每一项
把每一项作为新对象的属性名和属性值存起来,例如当前项1,则[1,1];
所以以后如果出现相同的属性名,则删除该项,typeOf obj.[xxx]===undefined;则该项不是重复值在原型上添加一个数组去重的方法
Array.prototype.myDistinct= function () {
let obj={};
for (let i = 0; i < this.length; i++) {
let item= this[i];
if(typeof obj[item]!=='undefined'){//该项是重复的
this[i]=this[this.length-1];//用最后一项的值赋值给当前项,
this.length--;//将最后一项删除(上一步已将最后一项保存至前面)
i--;
continue;
}
obj[item]=item;
}
obj=null;
return this;
};
//另一种写法,不会改变原数组的相对顺序
Array.prototype.myDistinct = function myDistinct() {
let obj = {};
for (let i = 0; i < this.length; i++) {
let item = this[i];
if (obj[item] === this[i]) {
this.splice(i, 1);
i--;
continue;
}
obj[item] = item;
}
obj = null;
return this;
};
冒泡排序
原理:让数组中的当前项和后面的每一项进行比较,如果当前项大于后一项,我们让两者交换位置(小—大),就好像是气泡升到表面一样,因此得名
总共比较:length-1次;
function bubble(ary) {
//->外层循环控制的是比较的轮数:
for (var i = 0; i < ary.length - 1; i++) {
//->里层循环控制每一轮比较的次数.
for (var k = 0; k < ary.length - 1 - i; k++) {
//ary[k]:当前本次拿出来这一项
//ary[k+1]:当前项的后一项
if (ary[k] > ary[k + 1]) {
//当前项比后一项大,我们让两者交换位置
var temp = ary[k];
ary[k] = ary[k + 1];
ary[k + 1] = temp;//可用结构赋值[ary[k],ary[k+1]]=[ary[k+1],ary[k]]; }
}
}
return ary;
}
每一轮从前到后两两比较,虽然不一定实现最后的排序效果,但是可以把当前最大的放在末尾
具体比较的轮数:ary.length-1 数组有多长,我们只需要把总长度-1个数分别放在末尾,即可实现最后的排序
对于数组[12, 13, 23, 14, 16, 11];
第一轮比较5次:一共六个,不需要和自己比较
第二轮比较4次:一共六个,不用和自己比,也不用和第一轮放在末尾的那个最大值比
第三轮比较3次
每一轮比较的次数 ary.length-1(不用和自己比)-当前已经执行的轮数(执行一轮向末尾放一个最大值,这些值不需要再比较)
数组中的深度克隆
首先使用JSON.Stringfy将数组转化为无意义的字符串,
在使用JSON.parse将字符串转化为对象