数组方法的重构,在一些面试中会经常遇到,这里对其中一部分方法的重构进行了汇总。

1 push方法实现
push就是在数组后面添加一个新元素,返回新数组的长度,数组改变

function push(arr,elem){
	// 将添加的元素放在数组的末尾
	arr[arr.length]=elem;
	return arr.length;
}
var arr = [1,2,5,6,7];
console.log(arr,push(arr,5);
打印输出:[1, 2, 5, 6, 7, 5] 6

2 pop方法实现
pop就是删除数组最后一个元素并且将其返回

function pop(arr){
	// 先把最后一个元素存储起来
	var elem = arr[arr.length-1];
	// 利用length--,可以删除最后一个元素
	arr.length--;
	return elem;
}
var arr = [1,2,5,6,1]
console.log(pop(arr)) 
打印输出: 1

3 unshift
在一个数组最前面插入一个或多个元素,返回长度

function unshift(arr){
	// 获取插入元素的个数
	var len = arguments.length-1;
	// 移位
	for(var i=arr.length-1;i>=0;i--){
		arr[i+len]=arr[i]
	}
	// 插入
	for(var j=1;j<arguments.length;j++){
		arr[j-1] = arguments[j];
	}
	return arr.length;
}
var arr=[2,5,6,8];
console.log(unshift(arr,5,1,2,3,6),arr)
打印结果: 9 (9) [5, 1, 2, 3, 6, 2, 5, 6, 8]

4 shift
删除第一个元素并返回
整体思路:将第一个元素存储起来,然后将数组每个元素前移一个位置,从前往后 1->0 2->1 3->2 这种

function shift(arr){
	var elem = arr[0];
	for(var i=0;i<arr.length;i++){
		// 元素前移,这里可以看出最后一个肯定为empty,因为数组最大为arr[arr.length-1] 根本就没有arr[arr.length]
		arr[i]=arr[i+1];
	}
	// 上面前移完毕,这里将最后一个空元素删了即可
	arr.length--;
	return elem;
}
var arr = [1,2,5,6,8];
console.log(arr,shift(arr));
打印结果: (4) [2, 5, 6, 8] 1

5 slice实现
slice就是截取某一段字符串,start 到 end 不包含end,如果end为负数,表示倒数第几个,最终返回一个新数组,但是原数组不会发生变化

function slice(arr,start,end){
	// 先将其全部转为Number型
	start = Number(start);
	end=Number(end);
	// 如果start 和 end是非数值的处理方法
	if(isNaN(start)) return start=0;
	if(isNaN(end)) end = arr.length;
	// 如果最后得到start > end 那么将得到一个 []空数组
	if(start<0) start+=arr.length;
	if(end<0) end+=arr.length;
	var arr1 = [];
	for(var i=start;i<end;i++){
		arr1[arr1.length] = arr[i];
	}
	return arr1;
}
var arr = [2,5,56,22,8];
console.log(slice(arr,2,4),arr)
打印结果: (2) [56, 22] (5) [2, 5, 56, 22, 8]

6 splice实现
截取某一段的数组元素,返回一个新的数组,原数组发生改变;利用它也可以对数组中的某些元素进行替换或者添加一些新的元素进去

function splice(arr,start,count){
	// 将字符转为数值型
	start = Number(start);
	count= Number(count);
	var a = [];
	// 如果start是一个非数值,返回一个空数组
	if(isNaN(start)) return a;
	// 针对start 和 count的值做出下面的判断,保证了start和count始终为正
	if(start<0) start+=arr.length;
	if(isNaN(count)) count=arr.length-start;
	// 根据count和start,将需要截取的元素push到一个新的数组,然后对原数组的内容进行替换
	for(var i=start,j=0;i<arr.length;i++,j++){
	if(j<count) a.push(arr[i]);
	// 在这个过程中每个数组元素都会前移count
	arr[i]=arr[i+count]
}
// 给需要插入的元素腾出位置,元素全部向后移动,根据删除元素的个数决定整体移动次数,从后开
for(var l=0;l<arguments.length-3;l++){
	for(var j=arr.length-1;j>=start+l;j--){
		arr[j+1]=arr[j];
	}
}
//将元素插入腾出来的位置中
for(var j=3;j<arguments.length;j++){
	arr[start+j-3] = arguments[j]
}
// 删除移动过程中产生的undefined元素
for(var i=0;i<count;i++){
	arr.length--;
}
// 返回新数组
return a;
}
var arr = [1,2,5,6,8];
// 从下标1开始删除两个元素,然后插入5,8,9三个元素
console.log(splice(arr,1,2,5,8,9),arr);
打印输出:(2) [2, 5] (6) [1, 5, 8, 9, 6, 8]

7 every实现
当数组中的元素全部都否和要求才返回true
整体思路:通过判断某一条件下返回的状态

function every(arr,fn){
// 对数组进行遍历
	for(var i=0;i<arr.length;i++){
		// 如果存在空元素跳过
		if(arr[i]===undefined) continue;
		// 如果某一个值运算后返回false,则直接返回false,后续不再执行
		if(!fn(arr[i],i,arr)return false;
	}
	// 如果全程没false出现,返回true
	return true;
}
var arr = [5,2,6,8,9,7];
var bool = every(arr,function(item){
	return item>1;
})
console.log(bool);
打印输出: true

8 some实现
只要有一个元素满足条件返回true,如果全部都不满足返回false
这个和every相反,写法基本相同

fucntion 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){
	return item > 10;
})
var arr = [1,2,5,6,9,8,7]
console.log(bool); 
打印结果: false

9 map实现
遍历数组,返回一个新的数组
思路:通过遍历数组,按照条件对数组中的每一项元素进行处理,返回一个新的数组

function map(arr,fn){
	var a = [];
	for(var i=0;i<arr.length;i++){
		if(arr[i]===undefined)continue;
		a[i]=fn(arr[i],i,arr);
	}
	// 返回新数组,原数组不变
	return a;
}
var arr = [1,2,45,5];
var arr1 = map(arr,function(item,index,arr){
	// 回调函数中对元素预处理
	return item+10;
})
console.log(arr1,arr);
打印结果: map.html:24 (4) [11, 12, 55, 15] (4) [1, 2, 45, 5]

10 forEach实现
forEach和map类似,只不过它没得返回值,它也可以遍历数组,并且可以进行一些预处理

function forEach(arr,fn){
	for(var i=0;i<arr.length;i++){
		if(arr[i]===undefined)continue;
		fn(arr[i],i,arr);
	}
}
var arr = [100,2,5,4];
var sum = forEach(arr,function(item,index,a){
	console.log(item+100,index,a)
})
打印结果: 元素组不变
200 0 (4) [100, 2, 5, 4]
102 1 (4) [100, 2, 5, 4]
105 2 (4) [100, 2, 5, 4]
104 3 (4) [100, 2, 5, 4]

11 filter实现
根据条件返回某些元素,过滤

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}
];
function filter(arr,fn){
	var arr1=[];
	for(var i=0;i<arr.length;i++){
		if(fn(arr[i],i,arr){
			// 如果元素符合条件,就将其存储在一个新的数组中
			arr1[arr1.length]=arr[i];
		}
	}
	// 最终将所有符合条件的元素返回一个新的数组
	return arr1;
}
var a = filter(data,function(item,index,data){
	return item.id===1005;
})
console.log(a,data) 
打印结果:元素组不变
0: {id: 1005, icon: "img/5.png", name: "餐饮4", num: 1, price: 50}
length: 1
__proto__: Array(0)

12 reduce实现
归并运算 比如累加求和等

function reduce(arr,fn){
	var sum = 0;
	for(var i=0;i<arr.length;i++){
		sum+=fn(0,arr[i],i,arr);
	}
	return sum;
}
var arr = [2,5,6,8];
var num = reduce(arr,function(value,item,index,arr){
	return value+item;
})
console.log(num);
打印输出: 21