Go to comments

JavaScript 数组常用方法

ECMAScript3.0 是最标准的方法,之前学过的一系列东西,包括之后学的一系列东西都是基于es3.0,es3.0是最基础、最全面,最强大的一个通式版本,


ES5.0 是在 ES3.0 的基础上加了几个新方法而已,还并不是所有浏览器都好使,新版本浏览器支持ES5.0,老版本浏览器还没升级到ES5.0(比如老版本IE)。


ES6.0 是在 3.0、5.0 的基础上又提出的一些新方法,ES6.0是一个强大、飘逸的版本,现在学的是 es3.0 包含 es5.0 的(有些方法就不区分es3和es5了),


本次数组的方法都是 ES3.0 的方法,ES3.0 数组的方法是数组最重要的一些方法,然后把 es3.0 的方法分为两类,一种是可以改变原数组的一类,一种是不可以改变原数组的一类,按照这个分类学。


数组常用的方法

改变原数组 push, pop, shift, unshift, sort, reversem, splice

不改变原数组 concat, join —> split, toString, slice


一、可以改变数组的方法

这些方法都是可以改变原数组的,意思是在原数组的基础上去改变,添加或者剪切

方法名作用用法
push()在数组最后一位添加

var arr = [1,2,3];

arr.push(4);

console.log(arr); // [1, 2, 3, 4]

pop()从最后一位减去(删除)
unshift()在数组前面添加,和push方法相反
shift()从数组前面减

var arr = [1,2,3];

arr.shift();

console.log(arr); // [2, 3]

reverse()反排数组
splise()截取,在截取处插入
sort()排序


push()

数组是引用值,是可以访问方法的,push方法是数组自己的不是什么包装类的

1. push是往数组添加数据的方法,添加任何类型的数据都可以

2. 在哪添加数据?在数组的最后一位添加数据

var arr = [];

console.log(arr.push(10)); // push是往数组里面放东西的,默认返回到是数组的长度"1",原来数组的长度是0
console.log(arr); // [10]

console.log(arr.push(11)); // 再调用数组push一个11进去,默认返回数组长度是2
console.log(arr); // [10, 11]

console.log(arr.push(9)); // 再push一个9进去,数组长度默认返回3
console.log(arr); // [10, 11, 9]


push方法还可以同时添加多个,怎么添加都行,这个方法特别的强大

var arr = [10, 11, 9];

arr.push(1,2,3,4,5,6,7); // 7

console.log(arr); // [10, 11, 9, 1, 2, 3, 4, 5, 6, 7]


我们自己写一个push方法,看看能不能覆盖系统的

1. push方法在Array原型上  Array.prototype.push 

2. 调用push能打印出"哈哈",说明可以覆盖系统的

var arr = [];

Array.prototype.push = function(){
  return "哈哈";
}

console.log(arr.push()); // 哈哈


在这个基础上重写一个 myPush 方法

1. 重写的push不能写形参,因为不知道要传多少位,所以只能用 arguments

2. push方法是把数据,放到数组的最后一位,怎么放到最后一位呢?

Array.prototype.myPush = function(){

  for(var i = 0; arguments.length > i; i++){
    // console.log(i, this.length);
    this[this.length] = arguments[i];
  }

  return this.length;
}


var arr = ['1origin' ,'2origin'];

console.log(arr.myPush(3,4,5,6)); // 6

console.log(arr); // ["1origin", "2origin", 3, 4, 5, 6]


思路:

比如数组  arr = [1,2]  里面已经有两位了,现在push一个数字3进去,3的位置应该在数组的最后一位

1. 数组从0位、1位开始算,数组的长度是的2

2. 长度2可以代表数组中有三位 0位,1位, 2位

3. push这个3应该在数组最后一位,而长度2表示数组的最后一位, arr[2]  中括号里的2是push进去3后数组的长度arr.length

4. 接下来再在给数组 arr = [1,2,3] 加一个4,arr[3] 中括号里面填的3,就是要往数组里面push的位置(最后一位)

所以,就是往数组第length位上填东西,因为length位还没出生呢,数组的最后一位永远是 length - 1 


实现方式:

1. 把arguments遍历一下,把arguments里面的每一个东西都拿出来,

2. 数组不存在时原型链就存在了,原型链上的方法不知道今后是谁会去调用,不知道谁调用拿this代替, this[this.length] 谁调用它谁是this,

下次循环的时候this.length的长度自动就加1了,不用我们自己加加,数组就有这个特性

和系统自带的push一样,最后把数组的长度返回 return this.length


为什么写这个方法呢?

一方面启发下思路看系统怎么来实现的,另一方面以后要学会在原型链上编程。


什么叫在原型链上编程?

在原型链上写咱们通用的方法,

比如数组去重,去重方法数组没给咱们提供,咱们需要写到原型链上,让以后所有的数组都可以实现这个方法。


pop() 

pop方法说删除不标准,先看效果

var arr = [1,2,3];


console.log(arr.pop()); // 返回3
console.log(arr); // 数组剩下[1, 2]


console.log(arr.pop()); // 返回2
console.log(arr); // arr数组变成[1]

pop方法把数组的最后一位,不叫删除叫剪切出去,是把数组的最后一位剪切出去


变量num的值是3,变量num是数组最后一位剪切出来的那个数

var arr = [1,2,3];

var num = arr.pop();

console.log(num); // 3

console.log(arr); // [1, 2]


pop在执行的时候不用传参,传了也白传

var arr = [1,2,3];

arr.pop(2); // 想剪切两位

console.log(arr); // [1, 2] 数组只剪切最后一个,传的参数被忽略


总结

pop就是从最后一位去剪切,

push就是从最后一位去增加,

它俩是相反的


 unshift() 

shift键盘上有这个键,unshift()方法别看加un了,但是unshift()方法是添加东西的


比如给数组增加一个 0

var arr = [1,2,3];

arr.unshift(0); // 返回数组的长度 4

console.log(arr); // [0, 1, 2, 3]

unshift()是在数组的前面加东西,和push()方向是相反的


unshift()是增加而且是在数组前面增加,那shift()是减从前面减

var arr = [1,2,3];

arr.shift(); // 1

console.log(arr); // [2, 3]


看看unshift能不能像push一样那么飘逸,加两个进去!

var arr = [1,2,3];

arr.unshift(-1, 0); // 返回数组长度 5

console.log(arr); // 数组变成 [-1, 0, 1, 2, 3]

unshift方法能加两个进去


unshift()像push()一样重写,怎么写?

先考虑插入的问题,看一个问题,数组能不能在它的负一位里面放东西?

var arr = [1,2,3];

arr[-1] = 0;

console.log(arr); // [1, 2, 3, -1: 0]

没用,不能这么往前插东西


怎么办?

定义一个新的数组,然后把两个数组拼到一起就可以了,而且数组还有拼接方法叫concat


不用concat方法,把参数当成一个新的数组,然后把原数组push到这个数组里就可以了,正好把原数组插入到新数组后面

Array.prototype.MyUnshift = function(newArr){

	var valArr = []; // 内部新建数组

	// 把argments挨个赋值给内部新数组valArr
	for(var i = 0; arguments.length > i; i++){
		valArr[i] = arguments[i];
	}

	// 把老数组(this) push给新valArr
	for(var i = 0; this.length > i; i++){
		valArr.push(this[i]);
	}

	// valArr已经是"参数新数组"在前,老数组this在后,
	// 再把valArr重新覆盖老数组this,完成改变原数组。
	for(var i = 0; valArr.length > i; i++){
		this[i] = valArr[i];
	}
	
	return this.length;

}

var arr = ["a",2,3];
 
console.log(arr.MyUnshift(5,6,"中文")); // 6

console.log(arr); // [5, 6, "中文", "a", 2, 3]


4、shift()

unshift() 在数组前面增加,shift() 方法从数组前面减

var arr = [1,2,3];


arr.shift(); // 1
console.log(arr); // [2, 3]


arr.shift(); // 2
arr.shift(); // 3
arr.shift(); // undefined


5、reverse()

reverse是逆反的意思,reverse() 方法逆转顺序后,它把原数组返回来,reverse不是返回新数组,改变的是原数组

var arr = [1,2,3];


console.log(arr.reverse()); // [3, 2, 1]

console.log(arr.reverse()); // [1, 2, 3]

console.log(arr); // [1, 2, 3]


6、splice()

splice()方法是除sort()以外相对复杂的一个方法了,而且它的应用非常多,splice是切片的意思


splice方法难就难在传参上,里面传了好些个参数

splice( 从第几位开始截取多少的长度在切口处添加新的数据 );


先看截取的功能不看切的

从第一位开始截取,截取两位

1. arr.splice( 1, 2 ) 从第一位开始,应该包含第一位截取两位

2. [1, 1, 2, 2, 3, 3]  返回的是截取的部分 [1, 2] 

var arr = [1, 1, 2, 2, 3, 3];

arr.splice(1,2); // 返回截取部分 [1, 2]

console.log(arr); // 再打印原数组剩下[1, 2, 3, 3]

3. 换句话说截取也是一种剪切,不是完全删除,想关注返回结果 [1, 2] 拿变量接收,不想关注就不接收


在控制台上操作,

image.png

截取后返回值 [1, 2]

截取后原数组变成 [1, 2, 3, 3]


再来,从第零为开始切,切三位,剩下的是什么?

var arr = [1, 1, 2, 2, 3, 3];


arr.splice(0, 3); // 返回[1, 1, 2]

console.log(arr); // 剩下[2, 3, 3]


再来,

1. 从第一位开始切,切一个,

2. 然后,后面加参数了,后面的参数是无穷个的个数,后面的参数包含什么意思呢?就是传多少个参数,都会把后面的参数全部放到切口处。传多少个都行,后面相当于在切口处的  push() 

var arr = [1, 1, 2, 2, 3, 3];


arr.splice(1, 1, 0, 0, 0); // [1]

console.log(arr); // [1, 0, 0, 0, 2, 2, 3, 3]

[1, 1, 2, 2, 3, 3]

[1, 1, 0, 0, 0, 2, 2, 3, 3]


那么问题来了,把4填到相应的位置上(3和5之间)怎么写?

var arr = [1, 2, 3, 5];


arr.splice(3, 0, 4); // []

console.log(arr); // [1, 2, 3, 4, 5]

[    1     ,     2    ,     3      ,           ,      5     ]

 第零位   第一位  第二位  第三位    第四位

1. 如果光标定位在第二位不切,光标不往后移,

2. 在第三位定位,光标切0位就是不切,

3. 不切在这块填4


再说明一下

1). 光标定位在第三位

2). 然后(这块很关键)然后光标就不切了,切0个,把刀疤留在这,不拿走东西,然后这块填东西

3). 不切这块填 4


splice方法用截取的次数概率比较小,用往里面填东西的概率比较大


有了splice方法之后,我们自己写的 MyUnshift 就好办了,在第0位开始截,截0个往里插东西就完事了,

splice方法是非常强大的,会把截取完的的片段给反回来,还改变原数组。


splice能从负数位开始截取吗?

-1开始截取,截取一个(一般的数组方法都带负位)

var arr = [1, 2, 3, 4];

arr.splice(-1 ,1); // [4] 截取出来了

console.log(arr); // [1, 2, 3]

负一位 -1 的意思是倒数第一位,数组一般的方法里面都可以带负位的


数组在内部怎么实现负数的?

比如spice方法它第一个参数(pos)肯定是位置,pos是怎么实现的,它是怎么把负数给归正的,也就是负一为什么是倒数第一位,为什么正一就是第二位?

var arr = [1, 2, 3, 4];

splice = function (pos){

    pos += pos > 0 ? 0 : this.length;

}


负一为什么是倒数第一位,为什么正一就是第二位?

如果传的是-1,数组的length是4,

公式:-1 + 4 = 3 ,结果3是数组最后一位4


如果传的是-2,数组的length是4,

公式:-2 + 4 = 2 ,结果2是数组正数二位3


PS:

编程尽量学完之后学的是编程,而不是学的是技术规律,技术规律没意思。

真正搞经济的人,真正在金融领域,高手之前都是编程的,我们这种程序化思维,特别有利于金融思维的启发。金融和编程是脱不了关系的,而且是相辅相成的。

所以把这个思维学会之后,想的是负数就是倒数第几位,可放到数字上实现的话就是另一种思维了,一定要学到这个过程,这是另一种思维法。


系统内部在实现length的时候,如果是负数的话,做这样一个兼容,如果是正数,正数就不用计算加了。

如果算负数,没法算负数,但是又想把负数的意义包含进来,怎么办法?加lenght就完事了。


如果越界,加一个判断(jQuery)

pos += pos > 0 ? 0 : this.length;

pos >= 0 || pos < length

算完的pos,要大于等于0或者pos小length,才有意义。


如果超界了,

数组的长度是5,放了一个 100 大于length不符合,

如果数组长度是5,放了一个 -100 它小于等于0了也不符合要求


7、sort()

arr是一个无序的数组,无序数组想变成有序的怎么办?arr.sort()  会自小到大的顺序

var arr = [1,3,4,0,-1,9]; 

console.log(arr.sort()); //  [-1, 0, 1, 3, 4, 9]

console.log(arr); // [-1, 0, 1, 3, 4, 9]

sort()方法就是给数组排序的,是在原数组的基础上更改


上面是从小到大升序,想要从大到下降序 arr.sort().reverse() 这就降序了

var arr = [1,3,4,0,-1,9];

console.log(arr.sort().reverse());// [9, 4, 3, 1, 0, -1]


换一个数组,用sort()方法升序排完是什么?

var arr = [1,3,5,4,10];

console.log(arr.sort()); // [1, 10, 3, 4, 5]

结果这不是我们理想中的排序


sort()把这些  [ 1, 3, 5, 4, 10 ]  全当成了字符按ASCII码排的,

sort()可以按ASCII码排序字符,但是这个排序不是我们想要的,和我们要的相差甚远,我们想要的是数字排序


所以sort()方法留了一个编程接口,里面填一个匿名的function函数,这个function通过自己的方法填充完之后,就可以让sort()方法按照我们想要的任何一种方式来排序

var arr = [1,3,5,4,10];

arr.sort(function(a, b){

    // 匿名函数

});

function里面必须要写两个形参,而且这个functin不用写名字,这就是一个函数引用


这个函数引用类似于把这个function写到外面,把函数名test填进去,也是填个引用进去

var arr = [1,3,5,4,10];


arr.sort(test); // 2.函数引用test填进去


function test(){ // 1.函数写在外边
}

所以,function莫不如直接在里面写了


这个function用不着我们自己去调用,把他当做参数传进去,系统会在适当的时候去调用,

只不过我们把function里面的规则写好就OK了


function里面的规则是什么呢?

1. 必须写两个形参

2. 看函数的返回值

    1). 当返回值为负数时,那么前面的数放在前面

    2). 当返回值为正数,那么后面的数在前面

    3). 返回值为0,不动 

var arr = [1, 3, 5, 4, 10];

arr.sort(function (a, b){

	return ;

});


sort会把里面的函数会调动无数次(具体多少次是可求的,有兴趣可以自己去求),每次执行的时候,会传里面两个参数

1). 首先第一次调用函数时时候,会把数组的第一位和第二位传进来,

     第一位是 1,

     第二位是 3,

     第一次调用函数时会把1, 3传进来,传进来通过一系列规则比较

2). 当返回值为正数的时候,后面的数在前,

     比如返回为 return 1;

     就会让 1, 3 调换位置为 3, 1 

     [3, 1, 5, 4, 10]

3). 当返回值为负数的时候,前面的数就在前,1,  3 不变

具体什么时候返回值为正,什么时候返回值为负,就是我们控制的了


var arr = [1, 3, 5, 4,10];  传参的顺序:

第一轮

第一次传  1 3

第二次传  1 5 

第三次传  1 4 

第四次传  1 10


第二轮

然后传     3  5

然后传     3  4 

然后传     3  10    


第三轮

然后传     5  4      [1, 3, 4, 5, 10]  4、5位置互换

然后传     4  10    [1, 3, 4, 5, 10]  位置不变 4 和 10 比较


第四轮

然后传     5  10    [1, 3, 4, 5, 10]

这是升序符合冒泡排序的算法


接下来定义规则,当a大于b的时候返回正数1,否则返回负数-1

var arr = [1, 3, 5, 4, 10];

arr.sort(function (a, b){

	if(a > b){
		return 1;
	}else{
		return -1;
	}

});

console.log(arr); //  [1, 3, 4, 5, 10]

第一遍传 1 3

1  3    [1, 3, 5, 4, 10] 

1  5    [1, 3, 5, 4, 10]

1  4    [1, 3, 5, 4, 10]

1  10  [1, 3, 5, 4, 10]


第二轮传 3和5比 

3  5    [1, 3, 5, 4, 10]

3  4    [1, 3, 5, 4, 10] 

3  10  [1, 3, 5, 4, 10]


第三轮传 5和4比

5  4    [1, 3, 4, 5, 10]  5大于4换位置,后面数在前,两个数换一下位置

4  10  [1, 3, 4, 5, 10]  然后这个位置的和那个位置的比,不要认数认位置,4跟10比小于,小于谁也不动


第四轮传 5和10比

5  10  [1, 3, 4, 5, 10]


这是升序,我们通过系统留的接口,自定义规则弄出来的升序


再排序一个数组

var arr = [2, 10, 20, 13, 4, 18, 9];

arr.sort(function (a, b){
	if(a > b){
		return 1;
	}else{
		return -1;
	}
});

console.log(arr); // [2, 4, 9, 10, 13, 18, 20]


2   10   [2, 10, 20, 13, 4, 18, 9]

2   20   [2, 10, 20, 13, 4, 18, 9]

2   13   [2, 10, 20, 13, 4, 18, 9]

2   4     [2, 10, 20, 13, 4, 18, 9]

2   18   [2, 10, 20, 13, 4, 18, 9]

2   9     [2, 10, 20, 13, 4, 18, 9]


10  20

10  13

10  4     [2, 10, 20, 13, 4, 18, 9]

4   18    [2, 4, 20, 13, 10, 18, 9]

4   9


每一轮进行完后,会最小得数放前面


20  13    [2,4,    20,13,10,18,9]

13  10    [2,4,    13, 20,10,18,9] 

10  18    [2,4,    10,20,13,18,9] 

10   9     [2,4,    9,20,13,18,10]  


前三位按循序了,第四位开始


20   13   [2,4,9,  20,13,18,10] 

13   18   [2,4,9,  13,20,18,10]

13   10   [2,4,9,  10,20,18,13] 


20   18   [2,4,9,10,  20,18,13]

18   13   [2,4,9,10,  18,20,13]

      [2,4,9,10,  13,20,18]


20   18   [2,4,9,10,13,    20,18]

      [2,4,9,10,13,    18,20]

这是数组sort()方法给我们的一个比较的顺序,比较的原则结合这个比较的顺序,就叫算法里面的冒泡排序,但今天讲的不是冒泡排序是数组的算法。


上面的完后是一个升序,变一下比较规则,当a小于b时返回降序

var arr = [2, 10, 20, 13, 4, 8, 9];

arr.sort(function(a, b){

	if(a < b){  // a小于b变降序
		return 1;
	}else{
		return -1;
	}

});

console.log(arr); // [20, 13, 10, 9, 8, 4, 2]


2   10      [10,  2,20,13,4,8,9] 2小于10,换位置 

10  20     [20,  2,10,13,4,8,9] 10小于20,换位置 

20  13     [20,  2,10,13,4,8,9]

20  4       [20,  2,10,13,4,8,9]

20  8       [20,  2,10,13,4,8,9]

20  9       [20,  2,10,13,4,8,9]


2  10      [20,10,  2,13,4,8,9] 2小于10,换位置

10  13    [20,13,  2,10,4,8,9] 10小于13,换位置  

13  4      [20,13,  2,10,4,8,9]

13  8      [20,13,  2,10,4,8,9]

13  9      [20,13,  2,10,4,8,9]


2   10   [20,13,10,  2,4,8,9] 2小于10,换位置

10  4    [20,13,10,  2,4,8,9]

10  8    [20,13,10,  2,4,8,9]

10  9    [20,13,10,  2,4,8,9]


2   4    [20,13,10,4  ,2,8,9] 2小于4,换位置 

4   8    [20,13,10,8  ,2,4,9] 4小于8,换位置 

8   9    [20,13,10,9  ,2,4,8] 8小于9,换位置 


2   4    [20,13,10,9,4,  2,8] 2小于8 换位置

4   8    [20,13,10,9,8,  2,4]  4小于8 换位置


2   4    [20,13,10,9,8,4, 2]  2小于4 换位置

           [20,13,10,9,8,4, 2]

这一系列换完之后变降序了,通过a小于b的改变,可以控制升序降序


想让数组升序,换回a大于b

var arr = [2, 10, 20, 13, 4, 8, 9];

arr.sort(function(a, b){

	if(a > b){  // a大于b变升序
		return 1;
	}else{
		return -1;
	}
});

console.log(arr); // [2, 4, 8, 9, 10, 13, 20]


怎么没计算0呢?

0反正也没变化,算它干嘛呢!

接下来简化一下,有没有什么通式?

第一个数比第二个数大,才调换位置一定是升序

a大b小要把b放前面,肯定是升序,能不能总结一个通式?


换一种写法

当 a - b > 0:大于0的时候,要返回一个大于0的数,就是返回 a - b 的结果就完事了

当 a - b < 0:小于0的时候,要返回一个小于0的数,直接返回 a - b 的结果就完事了


也就是升序排列

当 a - b 大于0的时候,返回a - b

当 a - b 小于0的时候,返回a - b

var arr = [2,10,20,13,4,18,9];

arr.sort(function(a, b){

	if(a - b > 0){
		return a - b;
	}else{ a - b < 0
		return a - b;
	}

});

console.log(arr); // [2, 4, 8, 9, 10, 13, 20]

就是无论什么时候返回"a - b"都是升序,

当a大于b到时候,返回的是一个负数,

当a小于b的时候,返回到是一个正数还是 a  -b

var arr = [2,10,20,13,4,18,9];

arr.sort(function(a, b){

	return a - b; // 升序

});

console.log(arr); // [2, 4, 9, 10, 13, 18, 20]


下面是降序的简化

a小于b的时候返回-1,a大于b的时候返回1

var arr = [2,10,20,13,4,18,9];

arr.sort(function(a, b){

	if(a < b){
		return 1;
	}else{
		return -1;
	}

});

console.log(arr); // [20, 18, 13, 10, 9, 4, 2]


a小于b就返回b - a就行了

a大于b要返回负数还是要返回b - a

var arr = [2,10,20,13,4,18,9];

arr.sort(function(a, b){

	if(a < b){
		return b - a;
	}else{
		return b - a;
	}

});

console.log(arr); // [20, 18, 13, 10, 9, 4, 2]


所以 return b - a 是降序

var arr = [2,10,20,13,4,18,9];

arr.sort(function(a, b){

	return b - a; // 降序

});

console.log(arr); // [20, 18, 13, 10, 9, 4, 2]


七、练习(面试题)

第一题:给一个有序数组乱序


原题,随机打乱原数组的顺序,然后在一次性返回。


乱序的结果,就是每次的结果都是不一样的,这次执行和下次执行不一样。

首先先铺垫一下 Math.random() 产生0到1之间的开区间数 [0, 1),每次都不一样,特别小的小数

console.log(Math.random()); // 0.03409055182865539

PS:

开区间就是不包括两头的数,不可能到0或1,

闭区间就是[0 ,1]包括0和1


随机数返回0到1之间的随机数,0到1之间想让它可正数、可负数怎么办?

Math.random() - 0.5   或  0.5 - Math.random() 


既然返回的是0到1之间的开区间数,让0.5减去这个开区间数,因为开区间数有可能是0到0.5之间,也有可能是0.5到1之间,

这样概率一半一半,有可能正、有可能负,这样每次返回的是随机的值

console.log( 0.5 - Math.random() );


再用sort()方法排序,就是随机乱排了

var arr = [1,2,3,4,5,6,7];

arr.sort(function(){

	return Math.random() - 0.5;

});

console.log(arr); // 每次结果都不一样


第二题:

把下面对象放到数组里面,按照的对象的年龄排序(升序)

var Fang = {
	name : "fang",
	age : 40,
	sex : "male",
	face : "amazing"
}
var Lili = {
	name : "lili",
	age : 37,
	sex : "female",
	face : "amazing"
}
var Glee = {
	name : "Lu",
	age : 36,
	sex : "female"  
}

var arr = [Fang, Lili, Glee]; // 把对象放到数组里

arr.sort(function (a ,b){

	if(a.age > b.age){
		return 1;
	}else{
		return -1;
	}

	// 还可以这样简化 return a.age - b.age;
});

console.log(arr);

关键知道原理是什么,把参数"a, b"用灵活了,知道原理想怎么排序怎么排


第三题:按照字符串长度排序

var arr = ['abc', 'bcd', 'ccc', 'dddd', 'asdfkhiuqwe', 'asdoifqwoeiur', 'asdf'];

arr.sort(function (a ,b) {

	return a.length - b.length;

});

console.log(arr); //["abc", "bcd", "ccc", "dddd", "asdf", "asdfkhiuqwe", "asdoifqwoeiur"]


第四题:按照字节长度排

var arr = ['abc莉莉', 'bcd莉', 'c莉', 'dddd莉', 'asdfkhiuqwe莉莉', 'asdoifqwoeiur', 'asdf'];

// 先封装一个方法,计算字节的长度
function retBytes(str){

	var num = str.length;
	
	for(var i=0; i < str.length; i++){
		if(str.charCodeAt(i) > 255){
			num ++;
		}
	}	
	return num;
}

arr.sort(function (a ,b) {

	return retBytes(a) - retBytes(b);

});

console.log(arr); // ["c莉", "asdf", "bcd莉", "dddd莉", "abc莉莉", "asdoifqwoeiur", "asdfkhiuqwe莉莉"]

先写一个retBytes方法返回字节长度,小功能实现完之后漫漫拓展,能成为一个很复杂的东西


二、不可以改变原数组的方法

这些方法特别简单 concat, join—>split, toString, slice

8、concat()

oncat()方法是链接两个数组,会把后面的数组(arr1)拼到前面的数组(arr)上,并且规则发生了改变。

var arr = [1,2,3,4,5,6];
var arr1 = [7,8,9];

console.log(arr.concat(arr1)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(arr1); // [7, 8, 9]

上面学过的都是能改变原数组的,这几个 concat, join—>split, toString, slice 是改变不了的,

改变不了的意思是concat()拼完是一个全新的数组,不影响原来的两个原数组。concat是计算机给英语造出来的词链接的意思


9、toString()

数组的toString()方法,就是把数组变成字符串展示出来,是数组自己重写的

var arr = [1,2,3,4,5,6];

var str = arr.toString();

console.log(str); // ”1,2,3,4,5,6”


10、slice()

slice()方法是截取和splice()有点相像又不一样,

slice()里面可以填0个参数,可以填一个参数,也可以填两个参数


先看填两个参数的 slice( 从该位开始截取, 截取到该位 不是截取了截取到

var arr = [1,2,3,4,5,6];

var newArr = arr.slice(1, 2); // 从第一位[2]开始截取,截取到第二位[3],不包括第二位[3]

console.log(newArr); // [2]

console.log(arr); // [1,2,3,4,5,6]

 [  1,          2,         3,        4,          5,        6];

第零位   第一位  第二位  第三位...

[1]是第零位,[2]是第一位,只截取到第二位[3]

从第一位开始截取,截取到第二位


看原数组还那样[1, 2, 3, 4, 5, 6],不改变原数组,关注的只能是返回值,所以slice截取完,千万要拿一个变量接收,否则slice没有意义。


从第一位开始截取,截取到第三位呢?

var arr = [1, 2, 3, 4, 5, 6];

var newArr = arr.slice(1 ,3);

console.log(newArr); // [2, 3]

console.log(arr); // [1, 2, 3, 4, 5, 6]


一个参数的情况是,从第几位开始截取,一直截取到最后

var arr = [1, 2, 3, 4, 5, 6];

var newArr = arr.slice(1);

console.log(newArr); // [2, 3, 4, 5, 6]

从第一位开始截取,一直截取到最后返回[2, 3, 4, 5, 6]


当然还可以填负数,从负四开始( -4 + 6 = 2 ),相当于从第二位开始

var arr = [1, 2, 3, 4, 5, 6];

var newArr = arr.slice(-4);

console.log(newArr); // [3, 4, 5, 6]

要是不懂负数,直接加length就完事了,当然系统提供负数是为了让我们更好的理解的,-4就是倒数第四个(倒数直接



Leave a comment 0 Comments.

Leave a Reply

换一张