JavaScript陣列操作函數總結分享

2022-07-04 14:02:27
本篇文章給大家帶來了關於的相關知識,其中主要整理了陣列操作函數的相關問題,包括了元素刪除、splice、slice、concat等等內容,下面一起來看一下,希望對大家有幫助。

【相關推薦:、】

陣列進階

上篇介紹了陣列的基本概念和一些簡單的陣列元素操作函數,實際上,陣列提供的函數還有很多。

pushpopshiftunshift是運算元組首尾兩端的函數,上文已經講過,本文不再贅述。

元素刪除(物件方式)

上篇已經簡單介紹過,陣列就是一個特殊的物件,因此我們可以嘗試使用物件的屬性刪除方法:delete

舉個例子:

let arr = [1,2,3,4,5];delete arr[2];console.log(arr);

程式碼執行結果如下:

image-20220601145054215

注意觀察圖中標黃的位置,雖然元素被刪除了,但是陣列的長度仍然是5,而且刪除掉的位置多了一個。如果我們存取下標為2的元素,會得到如下的結果:

image-20220601145329044

造成這種現象的原因是,delete obj.key是通過key移除對應值的,也就是說delete arr[2]刪除了陣列中的2:3鍵值對,當我們存取下標2時,就是undefined了。

而在陣列中,我們常常希望刪除元素後,元素的位置會被後繼的元素填補,陣列的長度變短。

這個時候,我們就需要splice()方法。

splice()

需要提前說明的是,splice()方法的功能相當豐富,並非只能刪除元素,以下是語法:

arr.splice(start[,deleteCount,e1,e2,...,eN])

splice方法從start位置開始,刪除deleteCount個元素,然後原地插入e1,e2,e3等元素。

刪除一個元素

以下範例可以從陣列中刪除一個元素:

let arr = [1,2,3,4,5]arr.splice(0,1);//刪除掉第一個元素1console.log(arr)

以上程式碼刪除陣列中第一個位置的1個元素,執行結果如下:

image-20220601150259266

刪除多個元素

刪除多個元素和刪除一個元素用法相同,只需要將第二個引數改為指定數量就可以了,舉例如下:

let arr = [1,2,3,4,5];arr.splice(0,3);//刪除前三個元素console.log(arr);//[4,5]

程式碼執行結果如下:

image-20220601150543923

截斷陣列

如果我們只提供一個引數start,那麼就會刪除陣列start位置後面的所有元素,舉個例子:

let arr = [1,2,3,4,5]arr.splice(2);//刪除從下標為2以及後面的所有元素console.log(arr);//[1,2]

程式碼執行結果:

image-20220601150813463

元素替換

如果我們提供了超過兩個引數,那麼就可以替換陣列元素,舉個例子:

let arr = [1,2,3,4,5];arr.splice(0,2,'itm1','itm2','itm3');console.log(arr);//['itm1','itm2','itm3',3,4,5]

程式碼執行結果如下:

image-20220601151303970

以上程式碼實際上執行了兩步操作,首先刪除從0開始的2個元素,然後在0位置插入三個新的元素。

元素插入

如果我們把第二個引數(刪除數量)改為0,那麼就可以只插入元素,不刪除元素,舉個栗子:

let arr = [1,2,3,4,5]arr.splice(0,0,'x','y','z')console.log(arr);//['x','y','z'1,2,3,4,5]

image-20220601151610031

返回值

splice()函數會返回被刪除的元素陣列,舉個例子:

let arr = [1,2,3,4,5]let res = arr.splice(0,3,'x','y')console.log(arr)//['x','y',4,5]console.log(res)//[1,2,3]

程式碼執行結果:

image-20220601152112459

負索引

我們可以使用負數指示開始操作元素的位置,舉個例子:

let arr = [1,2,3,4,5]arr.splice(-1,1,'x','y','z')console.log(arr)//[1,2,3,4,'x','y','z']

程式碼執行結果如下:

image-20220601152338186

slice()

slice()方法可以擷取指定範圍的陣列,語法如下:

arr.slice([start],[end])

返回一個新陣列,新陣列從start開始,到end結束,但是不包括end

舉例:

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

程式碼執行結果:

image-20220601152847094

slice()同樣可以使用負數下標:

let arr = [1,2,3,4,5]console.log(arr.slice(-3))//[3,4,5]console.log(arr.slice(-5,-1))//[1,2,3,4]

程式碼執行結果如下:

image-20220601153052200

如果只為slice()方法提供一個引數,就會和splice()一樣截斷到陣列末尾。

concat()

concat()函數可以將多個陣列或者其他型別的值拼接稱一個長陣列,語法如下:

arr.concat(e1, e2, e3)

以上程式碼將返回一個新的陣列,新陣列由arr拼接e1e2e3而成。

舉例:

let arr = [1,2,3]console.log(arr.concat([4,5],6,7,[8,9]))

程式碼執行結果如下:

image-20220601160305496

普通的物件,即使它們看起來和物件一樣,仍然會被作為一個整體插入到陣列中,例如:

let arr = [1,2]let obj = {1:'1',2:2}console.log(arr.concat(obj))

程式碼執行結果:

image-20220601161842657

但是,如果物件具有Symbol.isConcatSpreadable屬性,就會被當作陣列處理:

let arr = [1,2]let obj = {0:'x',
           1:'y',
           [Symbol.isConcatSpreadable]:true,
           length:2      }console.log(arr.concat(obj))

程式碼執行結果:

image-20220601162457853

forEach()

遍歷整個陣列,為每個陣列元素提供一個操作函數,語法:

let arr = [1,2]arr.forEach((itm,idx,array)=>{
    ...})

應用舉例:

let arr = [1,2,3,4,5]arr.forEach((itm)=>{
    console.log(itm)})

程式碼執行結果:

image-20220601162847982

let arr = [1,2,3,4,5]arr.forEach((itm,idx,array)=>{
    console.log(`arr[${idx}] in [${array}] is ${itm}`)})

程式碼執行結果:

image-20220601163106913

indexOf、lastIndexOf、includes

類似於字串,indexOflastIndexOfincludes可與查詢陣列中指定元素的下標:

  1. arr.indexOf(itm,start):從start位置開始搜尋itm,如果找到返回下標,否則返回-1;
  2. arr.lastIndexOf(itm,start):倒序查詢整個陣列,直至start處,返回第一個查到的下標(也就是陣列最後一個匹配項),找不到返回-1;
  3. arr.includes(itm,start):從start位置開始搜尋itm,找到返回true,否則返回false;

舉例:

let arr = [1,2,3,4,5,6,"7","8","9",0,0,true,false]console.log(arr.indexOf(0))//9console.log(arr.lastIndexOf(0))//10console.log(arr.includes(10))//falseconsole.log(arr.includes(9))//false

這些方法在比較陣列元素的時候使用的是===,所以false0是不一樣的。

NaN的處理

NaN是一個特殊的數位,三者在處理NaN有細微差別:

let arr = [NaN,1,2,3,NaN]console.log(arr.includes(NaN))//trueconsole.log(arr.indexOf(NaN))//-1console.log(arr.lastIndexOf(NaN))//-1

產生這種結果的原因和NaN本身的特性有關,即NaN不等於任何數位,包括他自己。

這些內容在前面的章節已經講過了,遺忘的童鞋記得溫故知新呀。

find、findIndex

在程式設計過程中常常會遇到物件陣列,而物件是不能直接使用===比較的,如何從陣列中查詢到滿足條件的物件呢?

這個時候就要使用findfindIndex方法,語法如下:

let result = arr.find(function(itm,idx,array){
    //itm陣列元素
    //idx元素下標
    //array陣列本身
    //傳入一個判斷函數,如果該函數返回true,就返回當前物件itm})

舉個栗子,我們查詢name屬性等於xiaoming的物件:

let arr =[
    {id:1,name:'xiaoming'},
    {id:2,name:'xiaohong'},
    {id:3,name:'xiaojunn'},]let xiaoming = arr.find(function(itm,idx,array){
    if(itm.name == 'xiaoming')return true;})console.log(xiaoming)

程式碼執行結果:

image-20220602162348472

如果沒有符合條件的物件,就會返回undefined

以上程式碼還可以簡化為:

let xiaoming = arr.find((itm)=> itm.name == 'xiaoming')

執行效果是完全相同的。

arr.findIndex(func)的用途和arr.find(func)幾乎相同,唯一不同的地方在於,arr.findIndex返回符合條件物件的下標而不物件本身,找不到返回-1

filter

findfindIndex只能查詢一個滿足要求的物件,如果一個陣列中存在多個滿足要求的物件,就需要使用filter方法,語法如下:

let results = arr.filter(function(itm,idx,array){
    //和find的用法相同,不過會返回符合要求的物件陣列
    //找不到返回空陣列})

舉個例子:

let arr =[
    {id:1,name:'xiaoming'},
    {id:2,name:'xiaohong'},
    {id:3,name:'xiaojunn'},]let res = arr.filter(function(itm,idx,array){
    if(itm.name == 'xiaoming' || itm.name == 'xiaohong')return true;})console.log(res)

程式碼執行結果:

image-20220602163621457

map

arr.map方法可以對陣列的每個物件都呼叫一個函數,然後返回處理後的陣列,這是陣列最有用的、最重要的方法之一。

語法:

let arrNew = arr.map(function(itm,idx,array){
    //返回新的結果})

舉例,返回字串陣列對應的長度陣列:

let arr = ['I','am','a','student']let arrNew = arr.map((itm)=>itm.length)//return itm.lengthconsole.log(arrNew)//[1,2,1,7]

程式碼執行結果:

image-20220602165142295

sort

arr.sort對陣列進行原地排序,並返回排序後的陣列,但是,由於原陣列已經發生了改變,返回值實際上沒有什麼意義。

所謂原地排序,就是在原陣列空間內排序,而不是新建一個陣列

let arr = ['a','c','b']arr.sort()console.log(arr)

程式碼執行結果:

image-20220602165914977

注意,預設情況下sort方法是以字母序進行排序的,也就是適用於字串排序,如果要排列其他型別的陣列,需要自定義比較方法

數位陣列

let arr = [1,3,2]arr.sort(function(a,b){
    if(a > b)return 1;
    if(a < b)return -1;
    return 0;})

程式碼執行結果:

image-20220602170310389

sort函數內部採用了快速排序演演算法,也可能是timsort演演算法,但是這些我們都不需要關心,我們只需要關注比較函數就可以了。

比較函數可以返回任何數值,正數表示>,負數表示<0表示等於,所以我們可以簡化數位比較方法:

let arr = [1,3,2]arr.sort((a,b)=> a - b)

如果想要逆序排列只需要交換一下ab的位置既可以了:

let arr = [1,3,2]arr.sort((a,b)=> b - a)

字串排序

別忘了字串比較要使用str.localeCompare(str1)方法呦

let arr = ['asdfas','success','failures']arr.sort((a,b)=>a.localeCompare(b))

程式碼執行結果:

image-20220602171526430

reverse

arr.reverse用於逆序陣列

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

這個沒啥好說的。

str.split()和arr.join()

還記得字串分割函數嗎?字串分割函數可以將字串分割成一個字元陣列:

let str = 'xiaoming,xiaohong,xiaoli'let arr = str.split(',')//['xiaoming','xiaohong','xiali']

冷門知識,split函數有第二個引數,可以限制生成陣列的長度

let str = 'xiaoming,xiaohong,xiaoli'let arr = str.split(',',2)//['xiaoming','xiaohong']

arr.join()方法用途和split方法相反,可以將一個陣列組合成一個字串。

舉個栗子:

let arr = [1,2,3]let str = arr.join(';')console.log(str)

程式碼執行結果:

image-20220602172244989

reduce、reduceRight

arr.reduce方法和arr.map方法類似,都是傳入一個方法,然後依次對陣列元素呼叫這個方法,不同的地方在於,app.map方法在處理陣列元素時,每次元素呼叫都是獨立的,而arr.reduce會把上一個元素的呼叫結果傳到當前元素處理方法中。

語法:

let res = arr.reduce(function(prev,itm,idx,array){
    //prev是上一個元素呼叫返回的結果
    //init會在第一個元素執行時充當上一個元素呼叫結果},[init])

試想一下,如何實現一個數位組成的陣列元素和呢?map是沒有辦法實現的,這個時候就需要使用arr.reduce

let arr = [1,2,3,4,5]let res = arr.reduce((sum,itm)=>sum+itm,0)console.log(res)//15

程式碼執行過程如下圖:

圖片1

arr.reduceRightarr.reduce用途相同,只不過從右往左對元素呼叫方法。

Array.isArray()

陣列是物件的一種特例,使用typeof無法準確的分辨二者的區別:

console.log(typeof {})//objectconsole.log(typeof [])//object

二者都是物件,我們需要使用Array.isArray()方法進一步做判斷:

console.log(Array.isArray({}))//falseconsole.log(Array.isArray([]))//true

some、every

arr.some(func)arr.every(func)方法用於檢查數位,執行機制和map類似。

some

對每個陣列元素執行傳入的方法,如果方法返回true,立即返回true,如果所有的元素都不返回true,就返回false

every

對陣列的每個元素執行傳入的方法,如果所有元素都返回true,則返回true,否則返回false

舉個例子:

let arr = [1,2,3,4,5]//判斷陣列是否存在大於2的元素console.log(arr.some((itm)=>{
    if(itm > 2)return true;}))//true//判斷是否所有的元素都大於2console.log(arr.every((itm)=>{
    if(itm > 2)return true;}))//false

thisArg

在所有的陣列方法中,除了sort,都有一個不常用固定引數thisArg,語法如下:

arr.find(func,thisArg)arr.filter(func,thisArg)arr.map(func,thisArg)

如果我們傳入了thisArg,那麼它就會在func中變為this

這個引數在常規情況下是沒什麼用處的,但是如果func是一個成員方法(物件的方法),而且方法中使用了this那麼thisArg就會非常有意義。

舉個例子:

let obj = {
    num : 3,
    func(itm){
        console.log(this)
        return itm > this.num;//查詢大於3的數位
    }}let arr = [1,2,3,4,5,6,7]let newArr = arr.filter(obj.func,obj)console.log(newArr)

程式碼執行結果:

image-20220602180424955

這裡我們可以看到,func中輸出的this就是我們傳入的thisArg值。

如果我們使用物件成員方法,同時不指定thisArg的值,就會造成thisundefined,從而導致程式錯誤。

【相關推薦:、】

以上就是JavaScript陣列操作函數總結分享的詳細內容,更多請關注TW511.COM其它相關文章!