JavaScript的Array知识汇总:包括数组基本操作,以及一些数组去重、冒泡排序、快速排序的一些实现思路
数组中常用方法
- pop、shift、unshift、splice、slice、
- concat、join、toString、sort、reverse、
- indexOf、lastIndexOf、forEach、map、
数组的基本结构
数组也是对象数据类型的
typeof [] ->'object'
数组也有属性名,只不过属性名是数字,我们把数字属性名称之为索引:数组是以数字作为数组,索引重0开始,length属性代表数组的长度
类数组:类似数组但不是数组
1、通过getElementsByTagName获取的元素集合是类数组
2、函数中的实参集合arguments也是类数组
……
- for循环和for…in循环的区别
- for循环只能遍历到数组私有的一些属性,而for…in循环可以把一些自定义的公共属性也能遍历出来
数组中的常用方法
数组中有很多常用的方法,查看数组方法 console.dir(Array.prototype)
学习的4个维度
- 1、方法的意义和作用
- 2、方法的形参
- 3、方法的返回值
- 4、通过此方法,原来的数组是否发生了改变
实现数组的增删改
增加
1 | var arr = [12,23,34] |
删除
1 | var remove_arr = [1,2,3,4] |
数组内置的方法 splice
1 | //=> splice;数组中的内置方法‘可以实现数组的增加、修改和删除 |
数组的查询和拼接
1 | var arr = [1,2,3,4] |
将两个数组进行拼接 concat
1 | - var arr = [1,2,3,4] |
数组转换成字符串
1 | var arr = [1,2,3,4] |
数组求和
1 | /* 已之数组中每一项都是数字,实现数组求和*/ |
数组中的排列和排序
1 | /* reverse:把数组中的每一项倒过来排列 |
验证数组是否包含某一项
1 | /* |
遍历数组的一些方法
1 | //->以下方法在IE6-8都不兼容 |
数组去重
- 方案一:双循环去重 遍历数组中的每一项,拿每一项和他后面的项依次比较,如果相同了,就把相同的这一项在原来的数组中删除即可
- 但是性能不好 循环次数太多
1 | var arr = [1,2,2,3,4,5,1,3,4,5,8,9,9,9,0,3,1,2] |
数组塌陷问题
1 | /* |
也可以直接避免数组塌陷 在删除的时候不进行j++
1 | for (var i = 0; i < arr.length-1; i++) { |
方案二:indexOf去重。 利用indexOf验证当前数组中是否包含这一项,包含就把当前项删除掉(不兼容IE6-8)
1 | //拿到当前这一项的时候去比对除了自身这一项 |
1 | var arr=[]; |
方案三 对象去重法
- 遍历数组中的每一项,把每一项作为新对象的属性名和属性值存起来,例如:当前项是1,对象存储的是{1:1}
- 在每一次向对象存储之前,首先看一下原有对象中是否包含这个属性(typeof obj[xxx] === ‘underfind’说明没这个属性)
- 如果已经存在这个属性,说明数组中的当前项是重复的(1在数组中删除这一项 2不再像对象中存储这个结果)
- 如果不存在(把当前项作为对象的属性名和属性值存储进去即可)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var arr = [1,2,2,3,4,5,1,3,4,5,8,9,9,9,0,3,1,2]
var obj = {}
for (var i = 0; i < arr.length; i++) {
var cur = arr[i]//当前遍历的对象 当前项
if(typeof obj[cur] !== 'undefined'){
//对象中已存在该属性:证明当前项时数组中的重复项
//如果重复了把当前项删除
arr.splice(i,1); //splice删除会造成索引向前进一位,数据过多消耗性能很大
i--;
continue; //条件成立遇见continue 下边不执行
//条件不成立遇不到continue 下边条件执行 相当于if(){}else()
}
obj[cur] = cur; //obj[1]= 1 {1:1}
} - 性能优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var arr = [1,2,2,3,4,5,1,3,4,5,8,9,9,9,0,3,1,2]
var obj = {}
for (var i = 0; i < arr.length; i++) {
var cur = arr[i]//当前遍历的对象 当前项
if(typeof obj[cur] !== 'undefined'){
//对象中已存在该属性:证明当前项时数组中的重复项
//如果重复了把当前项删除
/*性能优化*/
//=>思路 我们把最后一项拿过来替换当前要删除的一项,然后再把最后一项删除就不会造成所有索引改变
arr[i] = arr[arr.length-1]
arr.length--;//删除最后一项
i--;//当前项更改 下一次的时候还要比较一下当前项才对
continue; //条件成立遇见continue 下边不执行
//条件不成立遇不到continue 下边条件执行 相当于if(){}else()
}
obj[cur] = cur; //obj[1]= 1 {1:1}
}排序
冒泡排序
- 原理:让数组中的当前项和后一项进行比较,如果当前项大于后一项,我们就让两者交换位置
- 让数组中的当前项和后一项进行比较,如果当前项大于后一项,我们就让两者交换位置
1 | /* |
- 冒泡排序i–和i++的区别在于i是重0开始还是数组的最大值开始
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function bubble(ary) {
//i 外层循环控制的是比较的轮数
for (var i = ary.length - 1;i>0; i--) {
//里层循环控制每一轮的次数 i已经执行的轮数
for (var j = 0; j < i; j++) {
//ary[j]当前拿出来的这一项
//ary[j+1]当前项的后一项
if (ary[j] > ary[j + 1]) {
//->当前这一项比后一项还要大 两者交换位置
var temp = ary[j]//先把当前项给空瓶子 当前项空了
ary[j] = ary[j + 1]//当前项等于后一项 后一项又空了
ary[j + 1] = temp // 后一项等于之前存放当前项的瓶子 交换位置了
}
}
}
return ary;
}递归算法
- 原理: 函数自己调用自己// ->面试题:1-100之间,把所有能被3并且被5整除得的获取到,然后累加求和
1
2
3
4
5
6
7function fn(num){
console.log(num);
if(num === 0){
return;
}
fn(num-1)
} - 方案一 for循环 但是面试官或者不满意
1
2
3
4
5
6
7var total = null
for (var i = 1; i <= 100; i++) {
if(i%3 ==0 && i%5 ==0){//i%15也可以 最小公倍数
console.log(i)
total += i
}
} - 方案二 递归解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function fn(num){
if(num>100){
return 0;
}
if( num%3 ==0 && num%5 ==0){
console.log(num)
return num + fn(num + 1)
}
return fn(num + 1)
}
console.log(fn(1));
// 1 fn(2)
// 2 fn(3)
//....
// 15 15 + fn(16)
// 16 15 + fn(17)
//...
// 30 15+30 + fn(31) - 1-10以内所有偶数乘积
1
2
3
4
5
6
7
8
9
10function fn1(num){
if(num <1){
return 1;
}
if(num%2 ===0){
console.log(num)
return num * fn1(num - 1)
}
return fn1(num - 1)
}
快速排序
- var ary = [12,15,14,13,16,11]
- ->实现方式;先找中间这一项 14
- ->把剩余项中的每一个值和中间项进行比较,比他小的放在左边(新数组)比他大的放在右边(新数组)
- 每一个数组都按着这个规律找
1 | var ary = [12,15,14,13,16,11] |
插入排序
- 实现原理:把数组中的每一项理解为扑克牌 新抓一张然后对比一下 放入到小的后边
- 在桌面上新抓一张牌A,我们用A和手里已经抓的牌进行比较,如果A比手里当前要比较的这张牌小则继续往下一张牌比较,
- 一直遇到比手里这张牌大,则放到这张牌的后边
- 如果A比所有牌都要小,就把他放在最前边
1 | var ary = [12,15,14,13,16,11] |
数组中的最大值最小值
1、 数组排序法
- 首先给数组大小排序 然后第一个是最小值最后一个是最大值
1 | var ary = [12,23,34,36,24,25,35,14,25] |
2、使用Math中的max/min方法
- 他在执行的时候,把需要的那堆数一个个的传递进来,这样才可以得到最后的结果,一下放一个ary是不可以的
1 | var ary = [12,23,34,36,24,25,35,14,25] |
- apply改变this指向 传的数组也相当于是一个一个传的
1
2
3var ary = [12,23,34,36,24,25,35,14,25]
var max_ = Math.max.apply(null,ary)
var min_ = Math.min.apply(null,ary) - eval可以将字符串变成js表达式
1
2var ary = [12,23,34,36,24,25,35,14,25]
eval("Math.max(" + ary.toString() + ")")3、假设法
- 数组中第一个是最大值拿这个值和后边逐一进行比较,如果后边某一个值比假设的大就是假设错了 ,把假设值替换
- 和自定义属性一样都是js中最常用的方法
1 | var ary1 = [12,23,34,36,24,25,35,14,25] |
数组并列排序
1 | var datalist = [ |
- 代码优化
1
2
3
4
5
6
7
8
9
10
11
12function pass(a,b){
return b.count-a.count
}
datalist.sort(pass);
var id = 0;
for (var i = 0; i < datalist.length-1;i++){
datalist[i].count === datalist[i+1].count?datalist[i].id
= id:(function () {
datalist[i].id = id;id++javas
}());
i + 2===datalist.length?datalist[i + 1].id = id:''
}