Array内置对象的属性
数组方法:
sort(): arrayObject.sort(sortby);
sortby可选,规定排序顺序,但是必须是函数。sort() 方法用于对数组的元素进行排序。
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序,A在a之前。
要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
实际生产中,受限于服务器成本等因素,当单次数据查询成为整体性能瓶颈时,也会考虑通过将排序在前端完成的方式来优化性能。
function sortBy(a,b){ return a - b ;// 正序}
reverse():arrayObject.reverse()方法用于颠倒数组中元素的顺序。arrayObject.reverse(),该方法会改变原来的数组,而不会创建新的数组。
var arrs = [1,2,3,4];console.log(arrs.reverse()); //[4,3,2,1]
splice(): splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目组成的数组,该方法会改变原始数组。
arrayObject.splice(index,howmany,item1,.....,itemX);//实例如下var arr = new Array(6)arr[0] = "George"arr[1] = "John"arr[2] = "Thomas"arr[3] = "James"arr[4] = "Adrew"arr[5] = "Martin"var del = arr.splice(2,3,"William")del //["Thomas", "James", "Adrew"]arr //["George", "John", "William", "Martin"]
toString(): 将数组转换为一个字符串,并且返回这个字符串;这个字符串默认以","进行分割。
var arrs = [1,2];console.log(arrs.toString()); // 1,2
slice(): arrs.slice(start,end);从数组中截取一段,并返回。
start参数【必须】从何处开始选取(包括start),如果是负数,那么会从尾部选取,比如-1代表最后一个元素,-2代表倒数第二个元素,以此类推。
End参数【可选】规定是从何处结束选取(不包括end),如果没有指定该参数,那么数组会包含从start开始到数组结束的所有元素,如果该参数是负数的话,那么它规定的是从数组尾部开始算起的元素。
reduce(),归并方法:前向归并与
reduceRight(),后项归并
这两个的主要区别是从哪头开始遍历,迭代次数为ar.length - 1
var values = [1,2,3,4,5,6];var i = 1;var sum = values.reduce(function(prev,cur,index,array){ console.log("prev " + parseInt(prev)); console.log("cur " + parseInt(cur)); console.log("迭代次数 " + i++) return prev + cur;});console.log(sum); //输出结果prev 1cur 2迭代次数 1prev 3cur 3迭代次数 2prev 6cur 4迭代次数 3prev 10cur 5迭代次数 4prev 15cur 6迭代次数 521
var values = [1,2,3,4,5,6];var i = 1;var sum = values.reduceRight(function(prev,cur,index,array){ console.log("prev " + parseInt(prev)); console.log("cur " + parseInt(cur)); console.log("迭代次数 " + i++) return prev + cur;});console.log(sum);//输出结果//prev 6cur 5迭代次数 1prev 11cur 4迭代次数 2prev 15cur 3迭代次数 3prev 18cur 2迭代次数 4prev 20cur 1迭代次数 521
数组判断:
使用typeof不能测出来,因为数组是返回"object"的。
//方法1 自带的isArray方法,需要考虑IE8-var array6 = [];Array.isArray(array6 );//true//方法2 利用instanceof运算符,某些IE版本不兼容var array5 = [];array5 instanceof Array;//true //方法3 能力检测,测试是否具有数组的一些方法,如slice(); array.slice //方法4 利用toString的返回值,最好的方法function isArray(o) { return Object.prototype.toString.call(o) === ‘[object Array]‘;}
常见的数组问题:
1、数组高效去重
原理:新建一新数组,遍历传入数组,值不在新数组就加入该新数组中;
注意点:判断值是否在数组的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,需多写一些兼容低版本浏览器代码。
// 最简单数组去重法1function unique(array){ var n = []; //一个新的临时数组 //遍历当前数组 for(var i = 0; i < array.length; i++){ //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 if (n.indexOf(array[i]) == -1) n.push(array[i]); } return n;} // 借助于Set对象与...方法 [...new Set(arr)]
2、数组顺序扰乱
原理:每次从元数组中抽取一个,然后添加到新数组中,并在原数组中删除。
注意点:arrayObject.splice(index,howmany,item1,.....,itemX) : splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目(这里是一个数组)。该方法会改变原始数组。item是向数组中添加的新元素。
delete删除可以对数组和对象进行元素的删除,数组删除之后,使用Undefined来填补。对象就是删除属性的值(没有了)。
//每次随机抽一个数并移动到新数组中function shuffle(array) { var copy = [], n = array.length, i; // 如果还剩有元素则继续。。。 while (n) { // 随机抽取一个元素 i = Math.floor(Math.random() * array.length); // 如果这个元素之前没有被选中过。。 if (i in array) { copy.push(array[i]); delete array[i]; n--; } } console.log(array); console.log(copy); return copy;}shuffle([2,5,6,9,8,5]);
这样本来的数组也被改变了,变为空。如果在进入函数的时候把array赋值给另一个变量也是不可行的,因为数组的访问也是按引用的,除非深度复制一份副本(for循环)。不然使用delete||splice就会改变原来的数组。
3、数组求交集
原理:利用filter()方法,返回满足条件的值组成的数组。
相同使用方法的方法如下:
every():每项都(满足要求)为真则为真。
filter():返回为真的项组成的数组。
forEach():每一项都执行给定函数的操作,没有返回值。
map():执行函数操作,返回操作的返回值组成的数组。
some():任意项为真则为真。
以下是公用的模版形式:
var result = ArrObj.func(function(item,index,ArrObj){ return (item >2);//条件});
//利用filter和数组自带的indexOf方法array1.filter(function(n) { return array2.indexOf(n) != -1});
4、数组求并集
原理:连接连个数组并去重
注意:concat():concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。arrayObject.concat(arrayX,arrayX,......,arrayX)
function unique(arr1,arr2){ var a = arr1.concat(arr2),result = []; for (var i = 0,len = a.length;i
5、数组去重的实现
1、基本数组去重
原理:新建一个数组并返回,把原数组的元素在新建数组中没有存在的添加到新数组中。
Array.prototype.unique = function(){ var result = []; this.forEach(function(v){ if(result.indexOf(v) < 0){ result.push(v); } }); return result;}
2、利用hash表去重,这是一种空间换时间的方法,这里如果存在元素是引用类型的就会出问题的
原理:借助于一个对象来进行判断是否唯一
Array.prototype.unique = function(){ var result = [],hash = {}; this.forEach(function(v){ if(!hash[v]){ hash[v] = true; result.push(v); } }); return result;}
上面的方法存在一个bug,对于数组[1,2,'1','2',3],去重结果为[1,2,3],原因在于对象对属性索引时会进行强制类型转换,arr[‘1’]和arr[1]得到的都是arr[1]的值,因此需做一些改变:
Array.prototype.unique = function(){ var result = [],hash = {}; this.forEach(function(v){ var type = typeof(v); //获取元素类型 hash[v] || (hash[v] = new Array()); if(hash[v].indexOf(type) < 0){ hash[v].push(type); //存储类型 result.push(v); } }); return result;}
3、先排序后去重
Array.prototype.unique = function(){ this.sort(); var result = this; result.forEach(function(v,i){ if(v === result[i+1]){ result.splice(i,1); } }); return result;}[1,2,5,6,4,"1",2].unique();function randomArr(num,min,max){ var result = []; while(num--){ result.push(Math.floor(Math.random()*(max-min)) + min +1); } return result;}var arr = randomArr(20000,1,20000);console.log(arr.unique());
6、快速排序的实现
方法一(尽可能不用js数组方法):
function quickSort(arr){ qSort(arr,0,arr.length - 1);}function qSort(arr,low,high){ if(low < high){ var partKey = partition(arr,low,high); qSort(arr,low, partKey - 1); qSort(arr,partKey + 1,high); }}function partition(arr,low,high){ var key = arr[low]; //使用第一个元素作为分类依据 while(low < high){ while(low < high && arr[high] >= arr[key]) high--; arr[low] = arr[high]; while(low < high && arr[low] <= arr[key]) low++; arr[high] = arr[low]; } arr[low] = key; return low;}
方法二(使用js数组方法):
function quickSort(arr){ if(arr.length <= 1) return arr; var index = Math.floor(arr.length/2); var key = arr.splice(index,1)[0]; var left = [],right = []; arr.forEach(function(v){ v <= key ? left.push(v) : right.push(v); }); return quickSort(left).concat([key],quickSort(right));}
另外要知道,快速排序的平均时间复杂度O(nlogn),最坏情况是有序的情况,时间复杂度为n的平方,另外快速排序是不稳定的。
7、生成一个二维或者多维的数组,使用for循环来赋值
function to2Arr(x,y,r){ var resArr = new Array(y); var sArr = new Array(x); for (var i = 0; i < x; i++){ sArr[i] = r; } for (var j = 0; j < y; j++){ resArr[j] = sArr; } console.log(resArr); return resArr;}to2Arr(5,5,1);//行数、列数、初始值
如下的三维数组:
function to3Arr(x,y,z,r){ var resArr = new Array(y); var sArr = new Array(x); var res3deg = new Array(z); for (var i = 0; i < x; i++){ sArr[i] = r; } for (var j = 0; j < y; j++){ resArr[j] = sArr; } for(var k = 0;k < z; k++){ res3deg[k] = resArr; } console.log(resArr); console.log(res3deg); return res3deg;}to3Arr(5,5,5,1);
如下生成一个数组乘积的二维数组:
function fn(n,arr){ var arr2deg = new Array(); for(var i=0;i
8、对数组进行循环的时候,如果不知道需要循环几次就把for方法放在一个函数中,然后使用for来调用
如下这般:
function func(n,arr,m,maxlen){ var res = arr; for(var i=0;i