数组概念
- 用[]包起来的,一组有序的、任意数据类型的数据集合
- 数组的长度:array.length
- JS 中的数组与其他语言的数组,有很大的区别
创建数组的方式
1. 通过构造函数
// 创建空数组var array=new Array();
// 创建数组,并填充三个元素10,20,30var array=new Array(10,20,30);
// 创建数组,里面存储7个值var array=new Array(7);
2.通过字面量
var arr = [];
ES5数组方法
ECMAScript 5中对Array中新增了9个常用的方法:
5个迭代方法(循环操作数组中的各个项):forEach(),map(),filter(),every()和some()
2个归并方法(迭代数组所有项,最终返回一个值):reduce()和reduceRight()
2个索引方法:indexOf() 和 lastIndexOf();
ES5数组方法
push()
可以接受多个参数,并将这些参数放置于数组尾部,返回新数组的长度,原始数组发生改变。
Array.prototype.myPush =function(){
for (var i = 0; i < arguments.length; i++) {
//arguments代表实参的集合
//this 指向的是arr数组
this[this.length] = arguments[i];
}
//由于push 返回值 是一个数组的长度 所以 我们来个return;
return this.length;
};
arr.push(4,5,6);
alert(arr);
//-----结果 [1,2,3,4,5,6];
12345678910111213
pop()
不接收参数,从数组尾部删除一个元素,并返回这个删除的元素,原数组发生改变。
Array.prototype.myPop = function( ){
var len=this.length;
var result = this[len-1];
this.length = len - 1;
return result;
}
var a = [1,2,3,4]
console.log(a.myPop( ))//-----结果4;
console.log(a);//-----结果 [1,2,3];
123456789
unshift()
接受多个参数并,将这些参数放置于数组头部,返回新数组的长度,原数组发生改变。
Array.prototype.myUnshift=function( ){
var len=arguments.length-1;
this.length=this.length+len;
for(var i=this.length-1;i>=0;i--){
this[i+len]=this[i]
}
for(var j=1;j<arguments.length;j++){
this[j-1]=arguments[j]
}
return this.length
}
var arr=[1,2,5,6];
arr.unshift(10,11)//6
console.log(arr)//[10,11,1,2,5,6];
1234567891011121314
shift()
不接受参数,从数组的头部删除一个元素,并返回这个删除的元素,原数组发生改变。
Array.prototype.myShift = function(){
var result = this[0]
for(var i=0;i<this.length-1;i++){
this[i] = this[i+1]
}
this.length = this.length-1
return result;
}
var a = [1,2,3,4]
a.myShift()//1
console.log(a)//[2,3,4]
1234567891011
slice()
如果是一个参数,那么该参数表示的索引开始截取,直至数组结束,返回截取的数组,原数组不发生改变。
如果有两个参数,从第一个参数表示的索引开始截取,到第二个参数表示的索引结束,不包括第二个参数对应的索引位上的元素。
Array.prototype.mySlice = function () {
var startIndex = Number(arguments[0]),
endIndex = Number(arguments[1]),
newArr = [];
endIndex =endIndex === undefined ? this.length : Number(endIndex) ? Number(endIndex) : 0;
endIndex =endIndex < 0 ? Math.abs(endIndex) > this.length &&endIndex > -1? 0 :
this.length + Math.ceil(endIndex) :endIndex > this.length ? this.length : Math.floor(endIndex);
startIndex = startIndex ? startIndex < 0 ? Math.abs(startIndex) > this.length || startIndex > -1
? 0 : this.length + Math.ceil(startIndex) : startIndex > this.length ? this.length: Math.floor(startIndex) : 0;
for (var i = startIndex; i <endIndex; i++) {
newArr[newArr.length] = this[i];
}
return newArr;
};
var arr=[1,2,3,4,5];
var a1=arr.mySlice(1,3);
console.log(Array.prototype.slice.call({ 0:'a', 1:'b', length:2 }))// ["a", "b"]
console.log(a1)//[2, 3],
123456789101112131415161718
注; slice方法的一个重要应用,是将类似数组的对象转为真正的数组。
Array.prototype.slice.call({ 0:'a', 1:'b', length:2 }) /// ['a', 'b']
Array.prototype.slice.call(document.querySelectorAll("div"));
Array.prototype.slice.call(arguments);
123
上面代码的参数都不是数组,但是通过call方法,在它们上面调用slice方法,就可以把它们转为真正的数组。
var arr=[1,2,3,4,5,6];
var arr1=arr.slice(1,3);
var arr1=arr.slice( );
//如果没有任何参数就会从头截取到尾部 拷贝
var arr1=arr.slice(1);
//如果第二个参数没有,就会从开始截取到尾部
var arr1=arr.slice(-3,-1);
//如果是负数就会从后向前数,然后再截取
//前小于后将参数转换为正向数值时,前面的必须小于后面
var arr1=arr.slice(-3,5);
//如果第一个参数大于等于数组长度,或者第二个参数小于第一个参数,则返回空数组。
console.log(arr1,arr);
123456789101112
splice()
如果一个参数,那么从该参数表示的索引开始截取,直至数组结束,返回截取的数组,原数组发生改变。
如果有两个参数,从第一个参数表示索引,第二个参数表示的是截取的长度。
如果有三个及以上参数,从第一个参数表示索引,第二个参数表示的是截取的长度,后边的会从截取的位置添加至原数组里。
splice方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。
arr.splice(start, count, addElement1, addElement2, ...);
1
splice的第一个参数是删除的起始位置(从0开始也包含该元素),第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.splice(4, 2) ["e", "f"]
a ["a", "b", "c", "d"]
123
sort()
对数组的元素做原地的排序,并返回这个数组。sort可能不稳定,默认按照字符串的unicode码位点排序。改变数组;并返回操作后的原数组。
var arr = [2,11,50,7,9];
console.log(arr.sort());//按照字符串按位比较方式来判断大小的
arr.sort(function(a,b){
return a - b;//从小到大
return b-a;//从大到小
})
console.log(arr);
[10111, 1101, 111].sort(function (a, b) {return a - b;})
// [111, 1101, 10111]
[4, 3, 2, 1].sort( ) // [1, 2, 3, 4]
[11, 101].sort( ) ///[101, 11]
[
{ name:"张三", age:30 },
{ name:"李四", age:24 },
{ name:"王五", age:28 }]
.sort(function (o1, o2) {
return o1.age - o2.age;})
// [
// { name:"李四", age:24 },
// { name:"王五", age:28 },
// { name:"张三", age:30 }]
123456789101112131415161718192021
排序有三个经典排序方法:
1. 冒泡排序
//原理:数组中有n个数,比较相邻的两个数,如果后面的数小于前面的数,则两者交换。
//一轮完成后,此时最大的数据已经在最后,此时进行第二轮,确定倒数第二个数,依次几轮就可完成:
//1、从后向前循环
//2、内部从前向后循环到外层变量
//3、判断前面的值是否大于后面的值,交换
Array.prototype.Mpsort=function(){
var arr=this;
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--;
}
}
var arr=[1,2,4,6,3,2,6,8]
arr.Mpsort();
console.log(arr);
12345678910111213141516171819202122
2. 快速排序
//原理:取数组中间位置的数据,跟所有数据比较,比该数小的放一新数组,大的放一新数组,使用递归,拼接数据,最后得到想要的数组
//重新赋值给元素替换
Array.prototype.quickSort = function ( ) {
var arr=this
if (arr.length <= 1) { return arr; }
var item = arr.splice(parseInt(arr.length / 2), 1)[0];
// var item = arr.splice(Math.floor(arr.length / 2), 1)[0];
var leftArr = [];
var rightArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < item) {
leftArr.push(arr[i]);
} else {
rightArr.push(arr[i]);
}
}
return leftArr.quickSort().concat([item], rightArr.quickSort());
};
var arr = [1, 2, 34, 2, 1, 3, 2, 8]
arr=arr.quickSort();
console.log(arr)
12345678910111213141516171819202122
3. 选择排序
//选择排序;
//先找出最小或者最大的索引值,然后用当前的下标的元素与这个最小的元素比较
Array.prototype.mySort=function(){
var minIndex;
var arr=this;
for(var i=0;i<arr.length;i++){
minIndex=i;
for(var j=i+1;j<arr.length;j++){
minIndex=arr[minIndex]<arr[j]?minIndex:j;
}
var temp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=temp;
}
}
var arr=[1,2,4,5,6,32,2,2];
arr.mySort();
console.log(arr)
123456789101112131415161718
forEach()
跟for循环一样,只是forEach更灵活
用来遍历数组的,参数为一个回调函数,有三个值
1、e 当前元素
2、index当前元素索引值
3、array整个数组
.forEach(function(e,index,,arr){})
var arr = [1,2,3,4,5,6]
arr.forEach(function(e,index,array){
array[index]= e + 1
})
console.log(arr); //[2, 3, 4, 5, 6, 7]
map()
- map()方法返回一个被操作后的新数组,不会改变原数组
- 新数组的元素值是每次函数return的返回值;
- 若不写return,接收的新数组的元素值将全为空;
var a = [1,2,3];
var b = a.map(function(x){
return x*x; //b得值是[1,4,9]
});
filter()
过滤,过滤不符合条件的元素,如果回调函数返回true则保留,返回false则过滤掉
原数组不受影响;
通俗点说就是过滤器,过滤满足条件的数组的元素。
var arr = [20,13,11,8,0,11];
var brr =arr.filter(function(item)){
//返回值为奇数的元素
return item%2;
}
some()
判断数组内是否有指定元素,如果只要有一个则返回true,如果一个都没有则返回false
原数组不受影响;
var arr = [20,13,11,8,0,11];
var brr = arr.some(function(item){
return item>10;
})
alert(brr); //true
every()方法
判断数组内是否都有指定元素,如果全部都有则返回true,
如果有一个没有指定元素则返回false
原数组不受影响;
some()和every()相对;
some()是数组内只要有一个满足条件则返回true,一个都没有返回false
every()是数组内全部满足条件则返回true,否则返回flase
var arr = [20,13,11,8,0,11];
var brr = arr.every(function(item){
return item>10;
})
alert(brr); //false
reduce()
reduce()回调函数有四个参数:
第一个参数为:之前计算过的值,
第二个参数为:之前计算过的值的下一个值
第三个参数:当前索引
第四个参数为:当前数组对象
类似递归,可以求和之类的操作
let arr = [1,2,3];
let result = arr.reduce(function(prev, next, index, arr){
return prev + next;
})
console.log(result) // 6
reduceRight()
reduceRight()和reduce()类似,只是执行方向不同,
reduceRight()从数组的末尾往前递归
reduce()从数组的开头往后递归
indexOf()
跟字符串查找一样,查找指定元素是否存在,如果存在,返回下标,如果不存在返回-1
var a = ['Prosper', 'Lee', 'is', 'very', 'nice', '!!!']
console.log(a.indexOf("Pro")); // -1;
console.log(a.indexOf("is")); // 2
lastIndexOf()
跟indexOf()一样,只是查找起始点不同,indexOf是从第一个开始查找,
lastIndexOf()是从最后一个查找,如果存在,返回下标,如果不存在返回-1
var data = [2, 5, 7, 3, 5];
alert(data.lastIndexOf(5)); // 4