溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript中操作數(shù)組的方法實(shí)例分析

發(fā)布時(shí)間:2022-05-17 10:35:45 來源:億速云 閱讀:115 作者:zzz 欄目:大數(shù)據(jù)

這篇文章主要講解了“JavaScript中操作數(shù)組的方法實(shí)例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JavaScript中操作數(shù)組的方法實(shí)例分析”吧!

1. 與數(shù)據(jù)結(jié)構(gòu)相關(guān)的方法

有數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)的同學(xué)應(yīng)該都知道 棧 和 隊(duì)列 這兩種數(shù)據(jù)結(jié)構(gòu)。而 JavaScript  的數(shù)組方法中,有一些方法就是契合用數(shù)組實(shí)現(xiàn)的棧和隊(duì)列這兩種數(shù)據(jù)結(jié)構(gòu)的方法的。

1.1 Array.prototype.push

push() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回該數(shù)組的新長度。

是否改變原數(shù)組:是

參數(shù):

  • elementN:被添加到數(shù)組末尾的元素

  • 返回值:數(shù)組添加元素之后的 length 屬性值

這個(gè)方法 類似 于 棧 中的 推入 方法,它將一個(gè)元素入棧:

const stack = []; stack.push(1);  // 1 console.log(stack); // [1]  const stack1 = []; stack1.push(1, 2); // 2 console.log(stack1); // [1, 2]

1.2 Array.prototype.pop

pop()方法從數(shù)組中刪除最后一個(gè)元素,并返回該元素的值。此方法更改數(shù)組的長度。

  • 是否改變原數(shù)組:是

  • 參數(shù):無

  • 返回值:從數(shù)組中刪除的元素(當(dāng)數(shù)組為空時(shí)返回undefined)

這個(gè)方法 類似 于 棧 中的 彈出 方法,它將棧頂?shù)脑貜棾觯?/p>

const stack = [1, 2, 3, 4, 5]; stack.pop(); // 5 console.log(stack); // [1, 2, 3, 4]  const stack1 = []; stack1.pop(); // undefined console.log(stack1); // []

1.3 Array.prototype.unshift

unshift() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的開頭,并返回該數(shù)組的新長度(該方法修改原有數(shù)組)。

  • 是否改變原數(shù)組:是

  • 參數(shù):

  • elementN:要添加到數(shù)組開頭的元素或 多個(gè) 元素

  • 返回值:數(shù)組添加元素之后的 length 屬性值

這個(gè)方法 有那么點(diǎn) 類似于 隊(duì)列 的 入隊(duì) 操作,它將一個(gè)或者多個(gè)元素入隊(duì):

const queue = [3, 4, 5]; queue.unshift(2); // 4 console.log(queue); // [2, 3, 4, 5]  const queue1 = [3, 4, 5]; queue1.unshift(1, 2); // 5 console.log(queue1); // [1, 2, 3, 4, 5]

1.4 Array.prototype.shift

shift() 方法從數(shù)組中刪除第一個(gè)元素,并返回該元素的值。此方法更改數(shù)組的長度。

  • 是否改變原數(shù)組:是

  • 參數(shù):無

  • 返回值:從數(shù)組中刪除的元素(當(dāng)數(shù)組為空時(shí)返回undefined)

這個(gè)方法 有那么點(diǎn) 類似于 隊(duì)列 的 出隊(duì) 操作,也 有那么點(diǎn) 類似于 棧 的 彈出 操作:

const queue = [3, 4, 5]; queue.shift(); // 3 console.log(queue); // [4, 5]  const queue1 = []; queue1.shift(); // undefined console.log(queue1); // []

1.5 小結(jié)

其實(shí)之所以說 類似于 或者 有點(diǎn)類似于 ,還是因?yàn)?JavaScript  中本身并沒有提供嚴(yán)謹(jǐn)?shù)膶?shí)現(xiàn)隊(duì)列或者棧這種數(shù)據(jù)結(jié)構(gòu)的方法,但是通過這4個(gè)API的靈活使用,其實(shí)是可以比較靈活的實(shí)現(xiàn)類似于隊(duì)列或者棧的功能的。但是如果真的要在生產(chǎn)環(huán)境中用這個(gè)4個(gè)API來模擬棧或者隊(duì)列的話,不妨稍稍封裝一下。感興趣的同學(xué)不妨在學(xué)習(xí)棧以及隊(duì)列的知識(shí)后來試試哦。

1.6 自己實(shí)現(xiàn)一下試試?

我們接著不妨來實(shí)現(xiàn)一下上面的API是怎么做的。

1.6.1 仿寫 push

先來個(gè) push 看看:

Array.prototype.myPush = function(...args) {   let top = this.length;   for (let i = 0; i < args.length; i++) {     this[top] = args[i];     top++;   }   return this.length; };  const stack = []; stack.myPush(1); // 1 console.log(stack); // [1]  const stack1 = []; stack1.myPush(1, 2); // 2 console.log(stack1); // [1, 2]

注意:不要使用箭頭函數(shù),否則 this 的指向會(huì)出現(xiàn)一些問題,關(guān)于 this 指向的問題,因?yàn)椴皇潜酒诘闹攸c(diǎn),所以暫時(shí)不聊。

1.6.2 仿寫 pop

再試試 pop ?

Array.prototype.myPop = function() {   const topEle = this[this.length - 1];   this.length > 0 && this.length--;   return topEle; };  const stack = [1, 2, 3, 4, 5]; stack.myPop(); // 5 console.log(stack); // [1, 2, 3, 4]  const stack1 = []; stack1.myPop(); // undefined console.log(stack1); // []

1.7 小結(jié)

題外話,寫一個(gè)方法,無論是仿寫也好,還是自己發(fā)開也好。首先要確定的就是函數(shù)的入?yún)⒑头祷刂担蟛辉儋樖?。同時(shí),我個(gè)人是傾向于都寫純函數(shù)的。至于  unshift 和 shift 的仿寫,這里就不寫了,會(huì)稍微麻煩一點(diǎn),但是沒有太復(fù)雜。

2. 和順序有關(guān)的方法

2.1 Array.prototype.sort

sort()  方法用原地算法對數(shù)組的元素進(jìn)行排序,并返回?cái)?shù)組。默認(rèn)排序順序是在將元素轉(zhuǎn)換為字符串,然后比較它們的UTF-16代碼單元值序列時(shí)構(gòu)建的。

是否改變原數(shù)組:是

參數(shù):

  • compareFunction:用來指定按某種順序進(jìn)行排列的函數(shù)。如果省略,元素按照轉(zhuǎn)換為的字符串的各個(gè)字符的Unicode位點(diǎn)進(jìn)行排序。

  • 返回值:排序后的數(shù)組(原數(shù)組)

compareFunction

參數(shù):

  • a:用于比較的第一個(gè)元素

  • b:用于比較的第二個(gè)元素

返回值:number

描述:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 會(huì)被排列到 b 之前

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相對位置不變

  • 如果 compareFunction(a, b) 大于 0 , b 會(huì)被排列到 a 之前

簡而言之, sort 方法接受一個(gè)回調(diào)函數(shù)。這個(gè)回調(diào)函數(shù)的入?yún)閿?shù)組中待比較的兩個(gè)元素a 和 b,返回值是一個(gè) number , sort 根據(jù)  number 的值對數(shù)組進(jìn)行如上描述的操作。

看個(gè):chestnut::

const numbers = [4, 2, 5, 1, 3]; numbers.sort(function(a, b) {   return a - b; }); // [1, 2, 3, 4, 5]

排序這個(gè)東西吧,要是展開說內(nèi)容就太多了,這里就不展開了。

2.2 Array.prototype.reverse

reverse() 方法將數(shù)組中元素的位置顛倒,并返回該數(shù)組。數(shù)組的第一個(gè)元素會(huì)變成最后一個(gè),數(shù)組的最后一個(gè)元素變成第一個(gè)。該方法會(huì)改變原數(shù)組。

  • 是否改變原數(shù)組:是

  • 參數(shù):無

  • 返回值:顛倒后的數(shù)組(原數(shù)組)

沒啥好說的,就是反轉(zhuǎn)數(shù)組,那么來看個(gè):chestnut::

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

3. 和遍歷相關(guān)的方法

3.1 Array.prototype.every

every() 方法測試一個(gè)數(shù)組內(nèi)的所有元素是否都能通過某個(gè)指定函數(shù)的測試。它返回一個(gè)布爾值。

是否改變原數(shù)組:否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值:boolean (是否 所有元素 都通過 callback 的測試)

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:boolean

  • 描述:判斷當(dāng)前元素是否滿足 callback 的判斷條件

  • 舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const isMoreThanThree = (num) => {   return num > 3; };  test.every(isMoreThanThree); // false

3.2 Array.prototype.some

some() 方法測試數(shù)組中是不是至少有1個(gè)元素通過了被提供的函數(shù)測試。它返回的是一個(gè)Boolean類型的值。

是否改變原數(shù)組:否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值:boolean (是否 至少有1個(gè)元素 通過了 callback 的測試)

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:boolean

  • 描述:判斷當(dāng)前元素是否滿足 callback 的判斷條件

  • 舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const isMoreThanThree = (num) => {   return num > 3; };  test.some(isMoreThanThree); // true

3.3 Array.prototype.find

find() 方法返回?cái)?shù)組中滿足提供的測試函數(shù)的 第一個(gè)元素的值 。否則返回 undefined。

是否改變原數(shù)組:否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值:數(shù)組中第一個(gè)滿足所提供測試函數(shù)的元素的值,否則返回 undefined。

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:boolean

  • 描述:判斷當(dāng)前元素是否滿足 callback 的判斷條件

  • 舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const isThree = (num) => {   return num === 3; };  const isSeven = (num) => {   return num === 7; };  test.find(isThree); // 3 test.find(isSeven); // undefined

3.4 Array.prototype.findIndex

findIndex()方法返回?cái)?shù)組中滿足提供的測試函數(shù)的第一個(gè)元素的索引。若沒有找到對應(yīng)元素則返回-1。

和上面的非常類似,略。

3.5 Array.prototype.forEach

forEach() 方法對數(shù)組的每個(gè)元素執(zhí)行一次給定的函數(shù)。

是否改變原數(shù)組: 否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值: undefined

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:不需要

想想自己在剛接觸前端的時(shí)候,總是用錯(cuò)這個(gè)方法。無外乎是指令式的for循環(huán)用習(xí)慣了,并且編碼習(xí)慣不好。其實(shí)新同學(xué)們可以這么記:  兩個(gè)no&mdash;&mdash;不改變原數(shù)組、沒有返回值(返回值是undefined) 。好了,舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const log = (val) => {   console.log(val); };  test.forEach(log);  // 依次打印 1 2 3 4 5

3.6 Array.prototype.map

map() 方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素是調(diào)用一次提供的函數(shù)后的返回值。

是否改變原數(shù)組: 否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值:Array(一個(gè)由原數(shù)組每個(gè)元素執(zhí)行回調(diào)函數(shù)的結(jié)果組成的新數(shù)組。)

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:形成新數(shù)組的元素

曾經(jīng)總是把這個(gè)方法與forEach傻傻分不清,其實(shí)現(xiàn)在來看,還是英文沒學(xué)好。map 有映射的意思,簡直是明示啊。所以說,map  它會(huì)生成一個(gè)與原數(shù)組有映射關(guān)系的數(shù)組嘛。那么舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const double = (num) => {   return num * 2; };  const doubleList = test.map(double);  console.log(doubleList); // [2, 4, 6, 8, 10]

3.7 Array.prototype.filter

filter() 方法創(chuàng)建一個(gè)新數(shù)組, 其包含通過所提供函數(shù)實(shí)現(xiàn)的測試的所有元素。

是否改變原數(shù)組: 否

參數(shù):

  • callback:回調(diào)函數(shù)

  • thisArg:執(zhí)行 callback 時(shí)使用的 this 值

  • 返回值:Array(一個(gè)新的、由通過測試的元素組成的數(shù)組,如果沒有任何數(shù)組元素通過測試,則返回空數(shù)組。)

callback

參數(shù):

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:boolean

  • 描述:判斷元素是否通過測試

這個(gè)方法的命名也是一看就懂了,舉個(gè):chestnut::

const test = [1, 2, 3, 4, 5];  const isMoreThanThree = (num) => {   return num > 3; };  const moreThanThreeList = test.filter(isMoreThanThree);  console.log(moreThanThreeList); // [4, 5]

3.8 Array.prototype.reduce

reduce() 方法對數(shù)組中的每個(gè)元素執(zhí)行一個(gè)由您提供的reducer函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個(gè)返回值。

是否改變原數(shù)組: 否

參數(shù):

  • callback:回調(diào)函數(shù)

  • initialValue:作為第一次調(diào)用 callback函數(shù)時(shí)的第一個(gè)參數(shù)的值。 如果沒有提供初始值,則將使用數(shù)組中的第一個(gè)元素。  在沒有初始值的空數(shù)組上調(diào)用 reduce 將報(bào)錯(cuò)。

  • 返回值:函數(shù)累計(jì)處理的結(jié)果

callback

參數(shù):

  • accumulator: 累計(jì)器累計(jì)回調(diào)的 返回值 ; 它是上一次調(diào)用回調(diào)時(shí) 返回的累積值 ,或initialValue

  • element:數(shù)組執(zhí)行 callback 時(shí)的當(dāng)前元素

  • index:當(dāng)前元素的索引

  • array:調(diào)用方法的當(dāng)前數(shù)組

  • 返回值:boolean

  • 描述:判斷元素是否通過測試

這個(gè)方法,非常、非常強(qiáng)大,可以說幾乎在任何 迭代數(shù)組,并得到一個(gè)返回值 的場景下,都可以適用。

比如:

  • 數(shù)學(xué)計(jì)算:累加、階乘、求最大最小值......

  • 數(shù)組操作:去重、扁平化......

  • 函數(shù)式:pipe(從左往右執(zhí)行函數(shù)組合)

  • 等等

這里我們舉一個(gè)實(shí)現(xiàn)pipe的:chestnut::

const pipe = (...fns) => {   return (arg) => {     return fns.reduce((res, fn) => {       return fn(res);     }, arg);   }; };

3.9 小結(jié)

不難發(fā)現(xiàn),與數(shù)組迭代這類的方法,API都太相似了,而其實(shí)這些API語義化都是非常好的,多用用,自然就熟了。接著,不妨自己實(shí)現(xiàn)一個(gè)?

3.10 仿寫 reduce

Array.prototype.myReduce = function (fn, initialValue) {   let ret = initialValue || this[0];   let idx = initialValue ? 0 : 1;   while (idx < this.length) {     ret = fn(ret, this[idx], idx, this);     idx++;   }   return ret; };  const test = [1, 2, 3, 4, 5];  const add = (num1, num2) => {   return num1 + num2; };  test.myReduce(add); // 15 test.myReduce(add, 10); // 25

寫的相對粗糙,其他的方法思路也是類似,有興趣的同學(xué)可以自己寫來看看,寫完之后多少也能加深下理解。

4 其他方法

4.1 Array.prototype.flat

flat() 方法會(huì)按照一個(gè)可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合并為一個(gè)新數(shù)組返回。

  • 是否改變原數(shù)組: 否

  • 參數(shù):depth(指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1。)

  • 返回值:扁平化的數(shù)組(一個(gè)包含將數(shù)組與子數(shù)組中所有元素的新數(shù)組。)

曾經(jīng)我一直認(rèn)為扁平化這個(gè)方法在實(shí)際生產(chǎn)中用處不大。直到后來我維護(hù)的業(yè)務(wù)復(fù)雜起來后,需要用到 map  分類管理數(shù)據(jù)最后再取出來合并的時(shí)候,發(fā)現(xiàn)這方法還挺香的。舉個(gè):chestnut::

const test = [1, [2, 3], [4, [5, 6]]];  test.flat(1); // [1, 2, 3, 4, [5, 6]]  test.flat(2); // [1, 2, 3, 4, 5, 6]

自己實(shí)現(xiàn)個(gè)看看?其實(shí)我非常喜歡用棧來實(shí)現(xiàn)扁平化的思路,MDN上就有這個(gè)版本,但是我看相關(guān)文章提到這種方法的很少。

const test = [1, [2, 3], [4, [5, 6]]];  const flatten = (list) => {   const stack = [...list];   const ret = [];   while (stack.length) {     const topElem = stack.pop();     if (Array.isArray(topElem)) {       stack.push(...topElem);     } else {       ret.push(topElem);     }   }   return ret.reverse(); };  flatten(test); // [1, 2, 3, 4, 5, 6]

其實(shí)思路也是比較容易想到的:扁平化數(shù)組很明顯是一個(gè)需要深度搜索的過程,而深度搜索需要用到棧,那么之后套棧的模版就行了??赡苌晕⑿枰D(zhuǎn)一下的就是最后反轉(zhuǎn)數(shù)組這塊。當(dāng)然,如果按照完全符合常識(shí)來寫,那么每一步入棧的是一個(gè)反轉(zhuǎn)的元素就行了。

感謝各位的閱讀,以上就是“JavaScript中操作數(shù)組的方法實(shí)例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對JavaScript中操作數(shù)組的方法實(shí)例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI