一、算法之?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");