常見數(shù)組操作

實(shí)際工作中腥例,程序猿對數(shù)組的操作并不陌生辅甥,講到數(shù)組的操作方法能說出來幾個(gè),實(shí)際上我們對這些方法真的了解透了嗎燎竖?會改變原數(shù)組嗎璃弄,哪個(gè)方法的遍歷方式速度會更快,可以中斷遍歷嗎构回?這一章來研究一下常見的數(shù)組操作方法夏块,鞏固一下。


人丑多學(xué)習(xí).png

一纤掸、遍歷

1脐供、map(不改變原數(shù)組)
//currentValue 當(dāng)前值,index 當(dāng)前索引借跪,arr 源數(shù)據(jù)政己,thisValue可選參數(shù),執(zhí)行 callback 函數(shù)時(shí)值被用作this
array.map(function(currentValue,index,arr), thisValue)
array.map((currentValue,index,arr)=>{
})

不會檢測空數(shù)組

[].map((elem)=>{console.log(elem)})
//輸出:[]

返回一個(gè)新數(shù)組

var arr1=[1,2,3]
arr1.map((elem)=>{ return elem*2 })
//輸出:[2,4,6]
console.log(arr1)//[1,2,3]

map函數(shù)將數(shù)組中的元素按順序傳入回調(diào)函數(shù)垦梆,返回一個(gè)新的函數(shù)匹颤,所以不使用這個(gè)返回新數(shù)組,可以改用forEach或者for-of


萌萌分割圖.png

此處獻(xiàn)上一道前端經(jīng)典面試題

[0,1,2,3,8,10].map(parseInt)
//輸出啥呢托猩?

解題思路
懵逼1:傳入的parseInt作為回調(diào)函數(shù),如何執(zhí)行
懵逼2:如何讓它正常輸出數(shù)字

解這道題辽慕,我們需要知道的知識點(diǎn)
(1)京腥、首先了解下parseInt函數(shù) parseInt(string, radix)
string是必傳的,被解析的字符串溅蛉。
radix是可選參數(shù)公浪,表示要解析的數(shù)字的基數(shù)。該值介于 2 ~ 36 之間船侧。如果沒傳或者為0欠气,默認(rèn)是10。
(2)镜撩、前面我們了解到预柒,map函數(shù)接收三個(gè)參數(shù),當(dāng)前值袁梗,當(dāng)前值索引和原始數(shù)據(jù)宜鸯。
這道題實(shí)際上,在執(zhí)行的時(shí)候遮怜,是轉(zhuǎn)換成

//parseInt(當(dāng)前值淋袖,當(dāng)前值索引),返回一個(gè)新數(shù)組
[parseInt(0,0),parseInt(1,1),parseInt(2,2),parseInt(3,3),parseInt(8,4),parseInt(10,5)]
//[0, NaN, NaN, NaN, NaN, 5]
2锯梁、forEach(不改變原數(shù)組)
array.forEach(function(currentValue, index, arr), thisValue)

map和forEach的共同點(diǎn)
1即碗、循環(huán)遍歷數(shù)組中的每一項(xiàng)焰情,不能改變原數(shù)組
2、執(zhí)行的回調(diào)函數(shù)接收三個(gè)參數(shù)剥懒,當(dāng)前值内舟,當(dāng)前值索引,原數(shù)據(jù)
3蕊肥、只能遍歷數(shù)組
4谒获、不能中斷循環(huán)

map和forEach的差異
1、map會return一個(gè)新數(shù)組壁却,forEach函數(shù)return會報(bào)錯(cuò)
2批狱、forEach對于空數(shù)組是不會執(zhí)行回調(diào)函數(shù)的

如果想讓map和forEach中斷循環(huán)呢?

[1,2,33,333].map((elem,index)=>{
    if(index==2){
        break;
    }
    return elem*2
})
//VM176:3 Uncaught SyntaxError: Illegal break statement
//forEach也同樣會報(bào)錯(cuò)展东,此處省略啰嗦代碼~

在map和forEach過程中使用break都會報(bào)錯(cuò)赔硫,

3、for

最原始的遍歷for寫法盐肃,這種寫法需要規(guī)定好遍歷的邊界爪膊,同時(shí)也支持遍歷字符串

const arr = [1,2,4,6]
for(var i = 0, len = arr.length; i < len; i++){
    console.log(arr[i])
}
const string='勞資最漂亮'
for(let i=0;i<string.length;i++){
    console.log(string[i])
}

for循環(huán)可以中斷

for(var i=0;i<10;i++){
    if(i==5) break;
    console.log(i)
}//輸出0 1 2 3 4

for...in語句以任意順序遍歷一個(gè)對象的除Symbol以外的可枚舉屬性
for...of語句在可迭代對象(包括 Array,Map砸王,Set推盛,String,TypedArray谦铃,arguments對象等等)上創(chuàng)建一個(gè)迭代循環(huán)耘成,調(diào)用自定義迭代鉤子,并為每個(gè)不同屬性的值執(zhí)行語句驹闰。

var arr =[13,242,355]
for(var i in arr){ console.log(i,arr[i])}//
// 0 13
// 1 242
// 2 355
for(var i of arr){ console.log(i,arr[i])} //在每次迭代中瘪菌,將不同屬性的值分配給變量。
//13 undefined
// 242 undefined
// 355 undefined
var person={name:'monkey',age:18}
for(var i in person){ console.log(i)}// name  age
其他

前面提到的遍歷的第一個(gè)參數(shù)是回調(diào)函數(shù)嘹朗,第二個(gè)參數(shù)沒提到师妙,thisValue,是指傳入的this指向屹培。
來來來默穴,坐下繼續(xù)寫一道面試題,來理解一下惫谤。


好好學(xué)習(xí).png
var name='香菇'
const obj={
  name:'藍(lán)瘦',
  say:(index)=>{
    return this.name+index
  }
}
const arr=[1,2,3]
//輸出壁顶??
arr.map(obj.say,obj)// ["香菇1", "香菇2", "香菇3"]
const name='香菇'
const obj={
  name:'藍(lán)瘦',
  say:(index)=>{
    return this.name+index
  }
}
const arr=[1,2,3]
//輸出溜歪?若专?
arr.map(obj.say,obj)//["1", "2", "3"]

obj.say使用箭頭函數(shù),this指向全局windows蝴猪,前面兩題中唯一的差別是name變量是用const和var申明的调衰,而const申明的變量不會掛載到windows下膊爪,所以第一道var變量打印出來的是["香菇1", "香菇2", "香菇3"],第二道const申明的變量name無值嚎莉,結(jié)果是[1,2,3]米酬。

題目再轉(zhuǎn)變一下,如果不是箭頭函數(shù)

const name='香菇'
const obj={
  name:'藍(lán)瘦',
  say:function(index){
    return this.name+index
  }
}
const arr=[1,2,3]
//輸出趋箩?赃额?
arr.map(obj.say,obj)//["藍(lán)瘦1", "藍(lán)瘦2", "藍(lán)瘦3"]

這里的this指向的是obj本身,this.name等于藍(lán)瘦叫确。

超級變變變~~~如果這個(gè)時(shí)候不傳入this指向呢跳芳?

const name='香菇'
const obj={
  name:'藍(lán)瘦',
  say:function(index){
    return this.name+index
  }
}
const arr=[1,2,3]
//輸出?竹勉?
arr.map(obj.say)//["1", "2", "3"]

沒錯(cuò)飞盆,如果沒有傳this指向,這個(gè)時(shí)候指向的是windows次乓,this.name為空吓歇,輸出當(dāng)然就是["1", "2", "3"]

二、增刪

1票腰、push(改變原數(shù)組)
var arr=[1,2,4,5,6]
arr.push(9)//返回?cái)?shù)組長度  6
arr.push(10,11,12)//也可以同時(shí)追加多個(gè)元素
console.log(arr)//[1,2,4,5,6,9,10,11,12]

push操作會在數(shù)組最尾追加元素城看,返回?cái)?shù)組長度,改變原數(shù)組杏慰。

2析命、unshift(改變原數(shù)組)
var arr=[1,2,4,5,6]
arr.unshift(9)//返回?cái)?shù)組長度  6
console.log(arr)//[9,1,2,4,5,6]

unshift操作會在數(shù)組最前添加元素,同樣返回?cái)?shù)組長度逃默,改變原數(shù)組。

3簇搅、pop(改變原數(shù)組)
var arr=[1,2,4,5,7]
arr.pop()//返回被刪除的項(xiàng)  7
console.log(arr)//[1,2,4,5]

pop操作會在數(shù)組最后刪除元素完域,返回刪除項(xiàng),改變原數(shù)組瘩将。

4吟税、shift(改變原數(shù)組)
var arr=[1,2,4,5,7]
arr.shift()//返回被刪除的項(xiàng)  1
console.log(arr)//[2,4,5,7]

shift操作會在數(shù)組最前刪除元素,返回刪除項(xiàng)姿现,改變原數(shù)組肠仪。

push,pop备典,shift异旧,unshift這四個(gè)方法的操作類似棧和隊(duì)列方式
棧:后進(jìn)先出。通過push尾部追加和shift頭部刪除方法實(shí)現(xiàn)棧提佣。
隊(duì)列:先進(jìn)先出吮蛹。通過push和尾部追加和pop頭部推出實(shí)現(xiàn)隊(duì)列荤崇。

引入一個(gè)小知識點(diǎn)

const arr=['hello','world']
arr.length=0
console.log(arr[0])

按照上面題目,執(zhí)行arr.length=0
減少length屬性的值有一個(gè)副作用潮针,就是會刪除索引位于新舊長度值之間的元素术荤。因此arr[0]輸出為undefined。所以如果要清空一個(gè)數(shù)組每篷,可以設(shè)置數(shù)組length為0瓣戚,就能實(shí)現(xiàn)。

四焦读、查

1子库、find、findIndex
var arr=[1,2,4,5,6]
arr.find((elem,index,arr)=>{ //回調(diào)函數(shù)接收三個(gè)參數(shù)吨灭,當(dāng)前值刚照,索引和原數(shù)組
    return elem>3
})//4
arr.findIndex((elem,index,arr)=>{ 
    return elem>9
})//-1

find函數(shù)查找數(shù)組中符合條件的元素,并且返回符合條件的第一個(gè)值喧兄,如果不符合則返回undefined无畔。
findIndex函數(shù)則是返回?cái)?shù)組中第一個(gè)符合條件的元素索引,如果不符合則返回-1吠冤。

2浑彰、indexof
var arr =[13,242,355]
arr.indexOf(242)//存在則返回查找元素的索引值,否則返回-1拯辙,數(shù)組的indexof的用法和字符串的使用方式一樣郭变,返回元素的索引值。
3涯保、some
var arr=[1,2,4,5,6]
arr.some((elem,index,arr)=>{ //回調(diào)函數(shù)接收三個(gè)參數(shù)诉濒,當(dāng)前值,索引和原數(shù)組
    return elem>3
})//true

some函數(shù)返回一個(gè)布爾值夕春,只要數(shù)組中有一個(gè)元素滿足條件未荒,則返回true,否則返回false

4及志、every
var arr=[1,2,4,5,6]
arr.every((elem,index,arr)=>{ //回調(diào)函數(shù)接收三個(gè)參數(shù)片排,當(dāng)前值,索引和原數(shù)組
    console.log(elem,arr,index)
    return elem>0
})//true

every函數(shù)也是返回一個(gè)布爾值速侈,數(shù)組中所有的元素都要滿足條件才返回true率寡,只要有一個(gè)元素不滿足條件則返回false

5、includes
var arr=[1,2,4,5,6]
arr.includes(1)/true

includes反復(fù)也是返回一個(gè)布爾值倚搬,查詢數(shù)組中是否存在元素冶共。

以上5種方法都可以用于查詢,如果場景中需要返回true或者false,some比默、every幻捏、includes方法就滿足了。

五命咐、截取

1篡九、slice(不改變原數(shù)組)

slice:截取
slice方法是截取arr中的原數(shù),返回截取的元素集合
array.slice(start,end)

start:必需醋奠。規(guī)定從何處開始選取榛臼。如果是負(fù)數(shù),那么它規(guī)定從數(shù)組尾部開始算起的位置窜司。
end:可選沛善。規(guī)定從何處結(jié)束選取。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標(biāo)塞祈。如果沒有指定該參數(shù)金刁,那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素。如果這個(gè)參數(shù)是負(fù)數(shù)议薪,那么它規(guī)定的是從數(shù)組尾部開始算起的元素尤蛮。

var arr=[1,2,3,4,5,6]
arr.slice(2,5)//[3,4,5] 含頭不含尾截取
console.log(arr)//[1,2,3,4,5,6]   不改變原數(shù)組
arr.slice(3)//[4,5,6]

并且,slice可以實(shí)現(xiàn)淺克隆

var arr1=[1,2,3]
var arr2=arr1.slice()
arr1.push(4)
console.log(arr1)//[1,2,3,4]
console.log(arr2)//[1,2,3]
2斯议、splice(改變原數(shù)組)

splice:粘接
splice方法是截?cái)嘁徊糠謹(jǐn)?shù)據(jù)产捞,添加新項(xiàng)目,此方法會改變原數(shù)組哼御,返回被刪除的項(xiàng)目
array.splice(index,howmany,item1,.....,itemX)

index:必需坯临。整數(shù),規(guī)定添加/刪除項(xiàng)目的位置恋昼,使用負(fù)數(shù)可從數(shù)組結(jié)尾處規(guī)定位置看靠。
howmany:必需。要?jiǎng)h除的項(xiàng)目數(shù)量液肌。如果設(shè)置為 0衷笋,則不會刪除項(xiàng)目。
item1,.....,itemX:可選矩屁。向數(shù)組添加的新項(xiàng)目。

const arr=[1,2,3,4,5]
arr.splice(2,2,4,10,11)//返回被截?cái)嗟脑豙3,4] 
console.log(arr)//改變原數(shù)組爵赵,并且拼接新增[1,2,4,10,11,5]

六吝秕、反轉(zhuǎn)

1、reverse(改變原數(shù)組)

array.reverse()

const arr=[1,2,3,4,5]
arr.reverse()//[5,4,3,2,1]
console.log(arr)//[5,4,3,2,1]

返回反轉(zhuǎn)后的數(shù)組結(jié)果空幻,并且會改變原數(shù)組烁峭。

七、過濾

1、filter(不改變原數(shù)組)

array.filter(function(currentValue,index,arr), thisValue)

const arr=[2,3,4,5,7,8,12]
const arr2= arr.filter((elem,index,arr)=>{
  return elem>5
})
console.log(arr)//[2,3,4,5,7,8,12]
console.log(arr2)//[7,8,12]

filter函數(shù)會返回符合條件的元素集合约郁,不改變原數(shù)據(jù)缩挑。

八、克隆

淺克隆
1鬓梅、JSON.parse(JSON.stringfy())
2供置、array.slice(0)
3、array.concat([])
4绽快、Object.assign()
5芥丧、array.splice(0)

深克隆

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}
let deepClone=(obj)=>{
  if(typeof(obj)!=='object'||typeof(obj)!=='function') return obj
  let o = Array.isArray(obj)?[]:{}
  for(var i in obj){
    if(obj.hasOwnProperty(i)){
      o[i]=typeof(obj[i])==='obj'?deepClone():obj[i]
     }
  }
  return o
}

九、扁平化

1坊罢、flat(不改變原數(shù)組)

flat()可以拉平數(shù)組续担,只能拉平一層,用Infinity關(guān)鍵字無論嵌套多少層活孩,都可以轉(zhuǎn)為一維數(shù)組物遇。

const arr=[1,2,3,[2,43,6,[33,4,[55]]]]
console.log(arr.flat(Infinity))//[1, 2, 3, 2, 43, 6, 33, 4, 55]
console.log(arr)//[1, 2, 3, Array(4)]
console.log(arr.flat())//[1, 2, 3, 2, 43, 6, Array(3)]
生活好累.png

寫到這有點(diǎn)累,明天繼續(xù)補(bǔ)充憾儒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末询兴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子航夺,更是在濱河造成了極大的恐慌蕉朵,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阳掐,死亡現(xiàn)場離奇詭異始衅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缭保,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門汛闸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人艺骂,你說我怎么就攤上這事诸老。” “怎么了钳恕?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵别伏,是天一觀的道長。 經(jīng)常有香客問我忧额,道長厘肮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任睦番,我火速辦了婚禮类茂,結(jié)果婚禮上耍属,老公的妹妹穿的比我還像新娘。我一直安慰自己巩检,他們只是感情好厚骗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兢哭,像睡著了一般领舰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厦瓢,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天提揍,我揣著相機(jī)與錄音,去河邊找鬼煮仇。 笑死劳跃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浙垫。 我是一名探鬼主播刨仑,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼夹姥!你這毒婦竟也來了杉武?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤辙售,失蹤者是張志新(化名)和其女友劉穎轻抱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旦部,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祈搜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了士八。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片容燕。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婚度,靈堂內(nèi)的尸體忽然破棺而出蘸秘,到底是詐尸還是另有隱情,我是刑警寧澤蝗茁,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布醋虏,位于F島的核電站,受9級特大地震影響哮翘,放射性物質(zhì)發(fā)生泄漏灰粮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一忍坷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦佩研、人聲如沸柑肴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晰骑。三九已至,卻和暖如春绊序,著一層夾襖步出監(jiān)牢的瞬間硕舆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工骤公, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抚官,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓阶捆,卻偏偏與公主長得像凌节,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子洒试,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:在開發(fā)中垒棋,數(shù)組的使用場景非常多卒煞,平日中也涉及到很多數(shù)組的api/相關(guān)操作,一直也沒有對這塊內(nèi)容進(jìn)行一塊整理總...
    七色煙火閱讀 3,211評論 0 3
  • - concat()//鏈接數(shù)組 - slice()//從當(dāng)前數(shù)組中截取一個(gè)數(shù)組叼架,不影響原來的數(shù)組畔裕,參數(shù)start...
    HelloKing閱讀 545評論 0 0
  • Javascript有很多數(shù)組的方法,有的人有W3C的API碉碉,還可以去MDN上去找柴钻,但是我覺得API上說的不全,M...
    頑皮的雪狐七七閱讀 4,067評論 0 6
  • 一垢粮、數(shù)組定義 array() 1贴届、索引數(shù)組 在一個(gè)變量中,存儲一個(gè)或多個(gè)值蜡吧。數(shù)組中的每一個(gè)元素都有一個(gè)訪問ID毫蚓,根...
    竹與豆閱讀 526評論 0 0
  • foreach() | list() | extract | array_map() | array_walk()...
    彭曉華閱讀 849評論 0 0