第四節(jié) 數(shù)組去重和字符串 Math方法

一、算法之?dāng)?shù)組去重

方法一:

【簡(jiǎn)單思路實(shí)現(xiàn)】:依次拿出數(shù)組的中的每一項(xiàng),和后面的所有項(xiàng)進(jìn)行比較,如果有相同的就刪除。

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

/*

思路:

第一次:

? 拿出數(shù)組的第一項(xiàng):1

? ? ? ? ? ? ? ? 給[2,3,2,4]進(jìn)行比較,如果有重復(fù)就刪除

? 拿出數(shù)組的第二項(xiàng):2?

? ? ? ? ? ? ? ? ? ====[3,2,4]進(jìn)行比較,有重復(fù)的刪除 [3,4]?

? 拿出數(shù)組的第三項(xiàng):3

? ? ? ? ? ? ? ? ? ===4 進(jìn)行比較,有重復(fù)的刪除,沒有重復(fù)

? 還用拿最后一項(xiàng)4嗎?====不用了? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

依次拿出數(shù)組中的每一項(xiàng)給剩余的所有項(xiàng)進(jìn)行比較

*/

function unique(ary){

? ? for(var i=0;i<ary.length-1;i++){

? ? ? ? var getItem=ary[i];

? ? ? ? for(var j=i+1;j<ary.length;j++){

? ? ? ? ? var remainItem=ary[j];

? ? ? ? ? // 如果當(dāng)前項(xiàng)和后面的項(xiàng)在進(jìn)行比較的時(shí)候,相同就說(shuō)明重復(fù),要?jiǎng)h除掉原數(shù)組的那項(xiàng)

? ? ? ? ? if(getItem==remainItem){

? ? ? ? ? ? ? ary.splice(j,1);

? ? ? ? ? ? ? j--;

? ? ? ? ? }

? ? ? ? }

? }

? return ary;

}

console.log(unique(ary));

【splice造成的數(shù)組塌陷問(wèn)題】

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

for(var i=0;i<ary.length-1;i++){

? ? var current=ary[i];

? ? for(var j=i+1;j<ary.length;j++){

? ? ? ? var next=ary[j];

? ? ? ? if(current==next){

? ? ? ? ? ? ary.splice(j,1);

? ? ? ? ? ? j--;

? ? ? ? }

? ? }

}

console.log(ary)


方法二:

【實(shí)現(xiàn)的思路】利用對(duì)象屬性名不重復(fù)的思想,先建立一個(gè)空對(duì)象,然后依次循環(huán)數(shù)組中的每一項(xiàng),把此項(xiàng)作為obj對(duì)象的屬性名和屬性值,在添加的時(shí)候,如果這個(gè)屬性名對(duì)應(yīng)的值已經(jīng)存在,說(shuō)明此項(xiàng)重復(fù),刪除掉此項(xiàng)

/*

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

利用對(duì)象屬性名不能重復(fù)的原理:對(duì)象中如果沒有一個(gè)屬性的時(shí)候就是undefined

把數(shù)組中的每一項(xiàng)作為一個(gè)對(duì)象的屬性名和屬性值

var obj={1:1,2:2,3:3}

原理:如果對(duì)象屬性中已經(jīng)存在這個(gè)屬性名,我們就把原數(shù)組中此項(xiàng)進(jìn)行刪除

*/

function unique(ary){

? var obj={};

? for(var i=0;i<ary.length;i++){

? ? ? var item=ary[i];

? ? ? if(typeof (obj[item])!="undefined"){

? ? ? ? //如果此時(shí)對(duì)象的此屬性已經(jīng)有了,我們就應(yīng)該刪除數(shù)組中的那一項(xiàng)

? ? ? ? ary.splice(i,1);

? ? ? ? i--;

? ? ? ? continue;

? ? ? }

? ? ? obj[item]=item;

? }

? return ary;

}

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

var res=unique(ary2);

console.log(res);

【優(yōu)化方法】:對(duì)于數(shù)組塌陷,數(shù)組中后面所有的數(shù)字都要依次改變,這樣比較耗性能,怎么優(yōu)化呢?可以讓后面的索引值不變,這樣就可以省性能。

把最后一項(xiàng)的值拿過(guò)來(lái),占位到塌陷的此項(xiàng)

把最后一項(xiàng)刪除

需要注意,此時(shí)最后一項(xiàng)也需要比較所以還需要i--;

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

var obj={};

for(var i=0;i<ary.length;i++){

? var item=ary[i];

? if(typeof obj[item]!=="undefined"){

? ? ? ? // 把當(dāng)前重復(fù)的項(xiàng)替換成最后一項(xiàng)

? ? ? ? ary[i]=ary[ary.length-1];

? ? ? ? // 最后一項(xiàng)都已經(jīng)拿過(guò)來(lái)了,多余,所以刪除掉

? ? ? ? ary.length--;

? ? ? ? // 此時(shí)占位的這一項(xiàng)(最后一項(xiàng))還沒有比較,所以需要i--,再重新比較一次

? ? ? ? i--;

? ? ? ? continue;

? }

? obj[item]=item;

}

console.log(ary);

方法三:indexOf

創(chuàng)建一個(gè)新數(shù)組,遍歷原數(shù)組,如果新數(shù)組中沒有那一項(xiàng)的話,就把它push進(jìn)去

/*

? var ary2=[1,2,1,3,3,2,3];

? var newAry=[];

? 把原數(shù)組中的每一項(xiàng),只要在新數(shù)組中沒存在過(guò),我們就把它放進(jìn)去,最后newAry就是咱們最終要的數(shù)組

*/

function unique(ary){

? var newAry=[];

? for(var i=0;i<ary.length;i++){

? ? ? var item=ary[i];

? ? ? if(newAry.indexOf(item)==-1){

? ? ? ? newAry.push(item);

? ? ? }

? }

? return newAry;

}

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

var res=unique(ary2);

console.log(res);

二、算法之冒泡排序

? /*

? 冒泡排序:

? 從小到大排序

? var ary=[8,2,1,5]

? 原理:依次拿出數(shù)組中的每一項(xiàng)給后面的一項(xiàng)做對(duì)比,如果當(dāng)前項(xiàng)比后面的項(xiàng)大就交換位置

? 第一輪:[2,1,5,8] 經(jīng)過(guò)一輪比較出現(xiàn)了最大數(shù)

? 第二輪:[1,5,2,8] 經(jīng)過(guò)二輪比較得出倒數(shù)第2個(gè)數(shù)

? 第三輪:[1,5,2,8]? 經(jīng)過(guò)二輪比較得出倒數(shù)第3個(gè)數(shù)

? .... 總共四項(xiàng),經(jīng)過(guò)比三輪,已經(jīng)得到了三個(gè)最大數(shù)了,最后一個(gè)自然就是最小數(shù)

? 【需要比的總輪數(shù)】:ary.length-1;

? 【每次需要比的次數(shù)】:ary.length-1-已經(jīng)比較過(guò)的輪數(shù)

? 第一輪:4項(xiàng)兩兩比較需要比3次:ary.length-1

? 第二輪: 正常的ary.length-1-已經(jīng)比較過(guò)的輪數(shù)


? */

? function sort(ary){

? ? ? // 需要比較的輪數(shù)

? ? ? for(var i=0;i<ary.length-1;i++){

? ? ? ? ? for(var j=0;j<ary.length-1-i;j++){

? ? ? ? ? ? ? var current=ary[j];

? ? ? ? ? ? ? var next=ary[j+1];

? ? ? ? ? ? ? if(ary[j]>ary[j+1]){

? ? ? ? ? ? ? ? // 讓 ary[j]=ary[j+1]

? ? ? ? ? ? ? ? var temp=ary[j]

? ? ? ? ? ? ? ? ary[j]=ary[j+1];

? ? ? ? ? ? ? ? ary[j+1]=temp;


? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? }

? ? ? return ary;

? }

? var ary=[8,2,1,5];

? var res=sort(ary);

三、遞歸

自己調(diào)自己就是遞歸;

function fn(num){

? fn(num-1)

}

fn(10)

打印1 到10

// 打印1到10

function fn(num){

? ? if(num>10){

? ? ? ? return

? ? }

? ? console.log(num);

? ? fn(num+1);?

}

fn(1)

[練習(xí)題]:求一個(gè)1到100的所有數(shù)之和

答案一:

/*

? 1到100中所有數(shù)之和

*/

function total(star,end){

? ? var total=null;

? ? for(var i=star;i<=end;i++){

? ? ? ? total+=i;

? ? }

? ? return total;

}

var res=total(1,100);

console.log(res);

答案二:遞歸

function total(num){

? if(num>100){

? ? return 0;

? }

? return num+total(num+1);

}

total(1)

[練習(xí)題]:求1到100中同時(shí)能被2整除又能被3整除的所有數(shù)之和

答案:1

/*

求1-100所有能被2整除又能被3整除的所有數(shù)之和

*/

var total=null;

for(var i=1;i<=100;i++){


? if(i%2==0&&i%3==0){

? ? ? total+=i;

? }

}

console.log(total);

遞歸

function total(num){

? if(num>100){

? ? return 0;

? }

? if(num%2==0&&num%3==0){

? ? return? num+total(num+1);

? }

? return total(num+1);

}

var res=total(1);

四、算法之快速排序


/*

快速排序

var ary=[12,15,14,13,16,11];

原理:先拿出中間項(xiàng),然后把此項(xiàng)從數(shù)組中刪除掉,讓數(shù)組中的剩余項(xiàng)一一跟這個(gè)中間項(xiàng)做比較,新建兩個(gè)左右數(shù)組,如果大的項(xiàng)就放到右盒子,如果小的項(xiàng)就放到左盒子

[左盒子小]--中間項(xiàng)--[右盒子大]

依次再繼續(xù)重復(fù)相同的步驟,把左盒子和右盒子都進(jìn)行排序,直到出現(xiàn)空數(shù)組或者一項(xiàng)的時(shí)候停止

*/

function quickSort(ary){

? ? if(ary.length<=1){

? ? ? ? return ary;

? ? }

? var centerIndex=Math.floor(ary.length/2);

? // 拿到中間項(xiàng)的同時(shí),把中間項(xiàng)從數(shù)組中刪除掉

? var centerValue=ary.splice(centerIndex,1)[0];

? // 新建兩個(gè)數(shù)組:leftAry,rightAry;把a(bǔ)ry中剩余的項(xiàng),給中間項(xiàng)做對(duì)比,如果大項(xiàng)就放到右數(shù)組,小項(xiàng)就放到左數(shù)組.

? var leftAry=[],rightAry=[];

? for(var i=0;i<ary.length;i++){

? ? ? ? if(ary[i]<centerValue){

? ? ? ? ? ? leftAry.push(ary[i]);

? ? ? ? }else{

? ? ? ? ? ? rightAry.push(ary[i]);

? ? ? ? }

? ? }

? ? return quickSort(leftAry).concat(centerValue,quickSort(rightAry));

}

var ary=[12,15,14,13,16,11];

var res=quickSort(ary);

五、插入排序

var ary=[34,56,12,66,12];

插入排序:

新建一個(gè)數(shù)組:依次拿出原數(shù)組中的每一項(xiàng)往新數(shù)組里面插入,插入的時(shí)候需要遵循一個(gè)規(guī)律:

? ? ? ? ? ? ? 1)方向:從右向左

? ? ? ? ? ? ? 2)最終實(shí)現(xiàn)的效果,從小到大,在插入的時(shí)候,拿出的項(xiàng)

? ? ? ? ? ? ? 從右向左依次比較(新數(shù)組),如果拿出的項(xiàng)大(或者相等),就直接插入首次比它小的后面,

? ? ? ? ? ? ? 3)如果一直比到第一項(xiàng)了,條件還沒滿足,后面就是最小項(xiàng),直接放到數(shù)組的最前面

var newAry=[]

第一次====>我拿出第一項(xiàng)直接放進(jìn)去,不用進(jìn)行比較

? ? ? ? ? newAry=[34]

第二次====> 拿出56 [34,56]? ? ? ? ?

第三次====> 拿出12 [12,34,56]

第四次=====> 拿出66 [12,34,56,66]

第五次=====> 拿出12 [12,12,34,56,66]

*/

var ary=[34,56,12,66,12];

function insertSort(ary){

? //最終排序好的數(shù)組盒子

? var newAry=[];

? //拿出的第一項(xiàng)放進(jìn)去,此時(shí)盒子中只有一項(xiàng),不用個(gè)比較

? newAry.push(ary[0]);

? // 依次拿出原數(shù)組中的每一項(xiàng)進(jìn)行插入

? for(var i=1;i<ary.length;i++){

? ? ? var getItem=ary[i];

? ? ? // 在插入的時(shí)候需要跟新數(shù)組中的每一項(xiàng)進(jìn)行比較(從右向左)

? ? ? for(var j=newAry.length-1;j>=0;j--){

? ? ? ? ? var newItemAry=newAry[j];

? ? ? ? ? if(getItem>=newItemAry){

? ? ? ? ? ? // 如果拿出的項(xiàng)比某項(xiàng)大或者相等,就放到此項(xiàng)的后面

? ? ? ? ? ? newAry.splice(j+1,0,getItem);

? ? ? ? ? ? // 插入完畢,不用再繼續(xù)比較停止循環(huán);

? ? ? ? ? ? break;

? ? ? ? ? }

? ? ? ? ? if(j==0){

? ? ? ? ? ? //如果都已經(jīng)比到第一項(xiàng)了,還沒滿足條件,說(shuō)明這個(gè)就是最小項(xiàng),我們之間插入到數(shù)組的最前面

? ? ? ? ? ? newAry.unshift(getItem);

? ? ? ? ? }

? ? ? }

? }

? return newAry;

}

var res=insertSort(ary)



字符串

一、字符串的方法

@1、charAt

通過(guò)下標(biāo)去取值

var str = 'chengxiaohui';

// 通過(guò)下標(biāo)取值

var res = str.charAt(0);//"c"

// 如果找不到,返回值是空串

var res2 = str.charAt(12);//""

// 如果直接是索引去取值,找不到,返回是undefined

var res3 = str[12];//undefined

@2、charCodeAt

通過(guò)下標(biāo)取值對(duì)應(yīng)的ascii碼值

var str = 'chengxiaohui';

// 通過(guò)下標(biāo)取值

var res = str.charCodeAt(0);//99? "c"==>ASCII碼

console.log(res);//99

@3、indexOf/lastIndexOf

第一個(gè)參數(shù):找的內(nèi)容

第二個(gè)參數(shù):開始找的位置(indexOf)/找到哪終止(lastIndexOf)

一個(gè)參數(shù)的情況indexOf

var str = 'chengxiaohui';

// 一個(gè)參數(shù),在整個(gè)字符串中找

var res = str.indexOf("x");

// 返回值是找到的下標(biāo)

console.log(res);//5?

lastIndexOf

var str = 'chengxiaohui';

// 一個(gè)參數(shù),在整個(gè)字符串中找最后一次出現(xiàn)的下標(biāo)

var res = str.lastIndexOf("h");

// 返回值是找到的下標(biāo)

console.log(res);//9

兩個(gè)參數(shù)的情況:indexOf

var str = 'chengxiaohui';

// 從下標(biāo)5開始找,找"h"

var res = str.indexOf("h",5);

// 返回值是找到的下標(biāo)

console.log(res);//9

lastIndexOf

var str = 'chengxiaohui';

// 截止到下標(biāo)5,找"h"

var res = str.lastIndexOf("h",5);

// 返回值是找到的下標(biāo)

console.log(res);//1?

@4、slice

作用:查找字符串中特定位置的字符

參數(shù):(n,m) n:起始索引(包含), m結(jié)束索引(不包含)

返回值:查找的字符●從索引n(包括)開始查找到索引m(不包含)結(jié)束的字符●如果索引m不寫,就是查找到最后●如果n只寫一個(gè)0,或者不寫就是復(fù)制一份●也可以為負(fù)數(shù),轉(zhuǎn)換成正數(shù)的規(guī)律:str.length+負(fù)的索引值

var str="zhufengpeixun"

str.slice(1,3)? ? ===>"hu"

str.slice(0)? ? ? ===>復(fù)制一份

str.slice()? ? ? ===>復(fù)制一份

var res=str.slice(-3,-1);? ===>“xu”

@4.1、substring(n,m)

?subString? 和slice 基本都一樣,唯一不同在于,subString 不支持負(fù)數(shù)索引,而slice支持負(fù)數(shù)索引

@4.2、substr(n,m)

●作用:從索引n開始截取m個(gè)字符●參數(shù):n,m(個(gè)數(shù))●返回值:截取的字符串●也支持從負(fù)索引開始

var str="zhufengu";

var res=str.substr(-3,2);? ====>"ng"

@5、 toUpperCase()

toUpperCase(); 把字符串轉(zhuǎn)換為大寫

@6、?toLowerCase()

toLowerCase(); 把字符串轉(zhuǎn)換為小寫

@7、 replace()

作用:把字符串中某部分的字符替換成另一部分字符

參數(shù):(str1,str2)第一個(gè)參數(shù)代表的是要替換的字符或者是正則;第二個(gè)參數(shù)代表的是替換后的字符

返回值:替換后的字符串

var str="zhufeng2018zhufeng2019zhufeng";

var res=str.replace("zhufeng","珠峰");?

//===>"珠峰2018zhufeng2019zhufeng"

var res=str.replace(/zhufeng/g,"珠峰");

console.log(res)===>"珠峰2018珠峰2019珠峰"

@8、split()

作用:按照指定的字符把字符串分割成數(shù)組

參數(shù):分割符

返回值:分割后的數(shù)組

split? 和 join 對(duì)比記憶

var str="1-2-3";

var res=str.split("-");

console.log(res); ===> ?["1", "2", "3"]

二、練習(xí)題

1【時(shí)間字符串處理】把下面的字符串變成?"2019年08月18日 12時(shí)32分18秒"

var str="2019-8-18 12:32:18";

//var res=str.split(/-| |:/g)

var time=str.split(" ");

console.log(time) //["2019-8-18", "12:32:18"]

var timeLeft=time[0];

var timeRight=time[1];

var ary1=timeLeft.split("-"); //?["2019", "8", "18"]

var ary2=timeRight.split(":");// ["12", "32", "18"]

var result=ary1[0]+"年"+ary1[1]+"月"+ary1[2]+"日"+" "+ary2[0]+"時(shí)"+ary2[1]+"分"+ary2[2]+"秒"

console.log(result) //"2019年8月18日 12時(shí)32分18秒"

/*

? 補(bǔ)零

*/

function zero(num){

? ? return num<10?"0"+num:num;

}

var ss=zero(11);

var result=zero(ary1[0])+"年"+zero(ary1[1])+"月"+zero(ary1[2])+"日"+" "+zero(ary2[0])+"時(shí)"+zero(ary2[1])+"分"+zero(ary2[2])+"秒"

//"2019年08月18日 12時(shí)32分18秒"

2、queryURLParams 問(wèn)號(hào)參數(shù)處理


/*

? ? ? ? var? str ="https://www.baidu.com?name=zhufeng&age=10&id=14";

? ? ? ? {

? ? ? ? ? ? name:"zhufeng",

? ? ? ? ? ? age:10,

? ? ? ? ? ? id:14

? ? ? ? }

? ? ? */

? ? ? function urlParams(str){

? ? ? ? ? var obj={};

? ? ? ? ? var paramsStr=str.split("?")[1];

? ? ? ? ? if(paramsStr){

? ? ? ? ? ? ? //[name=zhufeng,age=10,id=14]

? ? ? ? ? ? ? var paramsAry=paramsStr.split("&");

? ? ? ? ? ? ? for(var i=0;i<paramsAry.length;i++){

? ? ? ? ? ? ? ? ? ? //name=zhufeng

? ? ? ? ? ? ? ? ? var item=paramsAry[i];

? ? ? ? ? ? ? ? ? //[name,zhufeng]

? ? ? ? ? ? ? ? ? var itemAry=item.split("=");

? ? ? ? ? ? ? ? ? obj[itemAry[0]]=itemAry[1];

? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? ? return obj;

? ? ? }

? ? ? var? str ="https://www.baidu.com?name=zhufeng&age=10&id=14";

? ? ? var result= urlParams(str);

三、Math常用的方法

Math稱之為數(shù)學(xué)函數(shù),它也是對(duì)象類型數(shù)據(jù),主要是用來(lái)操作數(shù)字的

1)Math.abs()? 求絕對(duì)值? ? //? Math.abs(-1)

2)Math.ceil/Math.floor

?向上取整,向下取整向上取整,無(wú)論是正數(shù)還是負(fù)數(shù),都取最大的值向下取整,無(wú)論是正數(shù)還是負(fù)數(shù),都取最小的值

Math.ceil(1.2)

2

Math.ceil(-1.6)

-1

Math.floor(1.8)

1

Math.floor(-1.1)

-2

3)Math.round() 四舍五入

正數(shù)的話,還是正常的,之前理解的,但是如果是負(fù)數(shù),臨界點(diǎn)必須大于5

Math.round(1.5)

2

Math.round(-1.5)

-1

Math.round(-1.51)

-2

4)Math.sqrt() 開平方

Math.sqrt(9)

3

5)Math.pow(n,m) 取冪n的m次冪

Math.pow(3,2)? ==> 9

6)Math.PI

Math.PI? ===>3.141592653589793

7)Math.max/Math.min? ?獲取最大值和最小值

Math.max(1,2,3)

Math.min(4,5,6)

8)Math.random() 獲取0~1 之間的隨機(jī)數(shù)(大于等于0,小于1)

獲取n 到m 之間的隨機(jī)數(shù):Math.random()*(m-n)+n;// 獲取10 到20 之間的隨機(jī)數(shù)

Math.random()*10+10

[升級(jí)版2]如果傳的實(shí)參中包含字符串,就變成數(shù)字,如果是非有效數(shù)字,就直接略過(guò)

function fn(){

? var total=null;

? for(var i=0;i<arguments.length;i++){

? ? ? var item=Number(arguments[i]);

? ? ? isNaN(item)?null:total+=item

? }

? return total;

}

[高級(jí)版3:es6]

functionfn(...arg){

returneval(arg.filter((item)=>!isNaN(item)).join("+"))

}

varres=fn(1,2,3,"3","3px");

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容