iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0

前言

今天會提到indexOf()find()filter()slice()splice() ,來看看有什麼常用的Array 方法吧。


Array.prototype.indexOf()

陣列中是否/是誰含有符合條件的值?

使用方法

Array.indexOf(searchElement[, fromIndex])

indexOf 會用嚴格比較(===)來找。

searchElement 是要找的元素。

fromIndex 是要從第fromIndex 開始找。

會以 callback 作為條件,篩選 array 中的元素,找到第一個就會結束迴圈。

實驗

  1. 只傳第一個值

如果陣列中有searchElement ,會得到 searchElement 在陣列中的索引值(index)

如果陣列中沒有searchElement ,會得到 -1

let testArr1 = ['pink', 'purple', 'green', 'white', 'skyblue']
let testArr2 = ['pink', 'purple', 'green', 'white', 'skyblue']
console.log(testArr1.indexOf('green'))
console.log(testArr2.indexOf('black'))

>> 2
>> -1

Array.prototype.find()

一找到就回報!

使用方法

Array.find(callback[, thisArg])

會以 callback 作為條件,篩選 array 中的元素,找到第一個就會結束迴圈。

實驗

使用find(),只會回報第一個找到的項目。

let testArray = [
    {name: 'apple', price: 30},
    {name: 'banana', price: 30},
    {name: 'cherry', price: 100},
    {name: 'melon', price: 70},
    {name: 'guava', price: 30},
    {name: 'pear', price: 50}
]
console.log(testArray.find(item => item.price > 50))

>> {name: 'cherry', price: 100}

Array.prototype.filter()

filter 是篩選的意思。

使用方法

array.filter(callback)

會以 callback 作為條件,一個個來篩選 array 中的元素,符合的會被加入新陣列。

可以用來篩選空值/undefined值,避免沒資料時取不到的狀況。

實驗

條件跟上一組find()是相同的,但結果不同,因為find只會找第一個符合條件的元素。

let testArray = [
    {name: 'apple', price: 30},
    {name: 'banana', price: 30},
    {name: 'cherry', price: 100},
    {name: 'melon', price: 70},
    {name: 'guava', price: 30},
    {name: 'pear', price: 50}
]
console.log(testArray.filter(item => item.price > 50))

>> [{name: 'cherry', price: 100}, 
    {name: 'melon', price: 70}]

Array.prototype.slice()

slice英文是片段;用在字串或陣列上都可以,這篇文章只先示範用在字串的結果~

可以用於淺拷貝,後面的文章可能(「可能」)會講到淺拷貝與深拷貝~~

MDN對於slice淺拷貝的說明如下:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
slice 不會修改原本的陣列,而是回傳由原本的陣列淺層複製的元素。原始陣列的元素會按照下列規則拷貝:

  • 如果該元素是個對象引用(不是實際的對象),slice 會拷貝這個對象引用到新的陣列內。兩個對象引用都引用了同一個對象。如果被引用的對象發生改變,則新的和原來的陣列中的這個元素也會發生改變。
  • 對於字串、數字、布林來說 (不是 StringNumber 或者 Boolean 對象), slice 會拷貝這些值到新的陣列內。在別的陣列內修改這些字串、數字或是布林,將不會影響另一個陣列。

使用方法

slice(startItem, (endItem))

startItem 代表從第幾個元素開始分成片段(0為第一項以此類推)。

endItem 非必要,表示分成片段後要在第幾個元素之前作為結尾。

什麼參數都不給的話就是直接複製陣列,淺拷貝的作用;給負數參數,則是會從陣列尾巴算過來擷取片段。

slice() 不會改變原本的陣列,而是會回傳新的一個陣列。

實驗

  1. 普通使用

傳正值

let testArr = ['00', '11', '22', '33', '44', '55']
console.log(testArr.slice(2, 4))

>> ['22', '33']

傳負值

let testArr = ['00', '11', '22', '33', '44', '55']
console.log(testArr.slice(-2))
>> ['44', '55']
let testArr = ['00', '11', '22', '33', '44', '55']
console.log(testArr.slice(-4, -1))
>> ['22', '33', '44']
  1. 用於多維陣列

修改第一層的陣列:假如改的是 StringNumber 或者 Boolean 對象,那原陣列與複製的陣列,將不會相互影響。實驗後結果確實是一樣的!

改 原來的陣列

let testArr = [['00', '000', '0000'], 
               '11', '22', '33', '44', '55']
let copyTestArr = testArr.slice(0, 2)
testArr[1] = '修改過的11'
console.log(testArr)
console.log(copyTestArr)

>> [['00', '000', '0000'], '修改過的11', '22', '33', '44', '55']
>> [['00', '000', '0000'], '11']

改 複製過的陣列

let testArr = [['00', '000', '0000'], 
               '11', '22', '33', '44', '55']
let copyTestArr = testArr.slice(0, 2)
copyTestArr[1] = '修改過的11'
console.log(testArr)
console.log(copyTestArr)

>> [['00', '000', '0000'], '11', '22', '33', '44', '55']
>> [['00', '000', '0000'], '修改過的11']

修改第二層的陣列,原陣列與複製的陣列,將會相互影響,兩個陣列都會改到。實驗後確認,結果一樣~

改 原來的陣列

let testArr = [['00', '000', '0000'], 
               '11', '22', '33', '44', '55']
let copyTestArr = testArr.slice(0, 2)
testArr[0][0] = '修改過的00'
console.log(testArr)
console.log(copyTestArr)

>> [['修改過的00', '000', '0000'], '11', '22', '33', '44', '55']
>> [['修改過的00', '000', '0000'], '11']

改 複製過的陣列

let testArr = [['00', '000', '0000'], 
               '11', '22', '33', '44', '55']
let copyTestArr = testArr.slice(0, 2)
copyTestArr[0][0] = '修改過的00'
console.log(testArr)
console.log(copyTestArr)

>> [['修改過的00', '000', '0000'], '11', '22', '33', '44', '55']
>> [['修改過的00', '000', '0000'], '11']
  1. 直接用 '=' 複製陣列,與用 slice() 的差別

為什麼不直接等於陣列就好,要用slice複製?以下實驗兩者的差異。

let testArr = [['00', '000', '0000'], 
               '11', '22', '33', '44', '55']
let sliceTestArr = testArr.slice()
let sameTestArr = testArr
testArr[1] = '修改過的11'
testArr[0][0] = '修改過的00'
console.log(testArr)
console.log(sliceTestArr)
console.log(sameTestArr)

>> [['修改過的00', '000', '0000'], '修改過的11', '22', '33', '44', '55']
>> [['修改過的00', '000', '0000'], '11', '22', '33', '44', '55']
>> [['修改過的00', '000', '0000'], '修改過的11', '22', '33', '44', '55']

Array.prototype.splice()

splice是拼接的意思。可以刪除,也可以刪除後增加項目。

使用方法

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

得到的會是:

(老規矩索引值從零起算)

  1. 傳入一個參數的狀況:array 從 第 start 項起(含該項),都要被拆掉。
  2. 傳入兩個參數的狀況:array 從 第 start 項起(含該項),往後數 deleteCount 項,要被拆掉。
  3. 傳入三個參數的狀況:array 從 第 start 項起(含該項),往後數 deleteCount 項,要被拆掉;並且再從 第 start 項,往後依序拚上 item1item2item3....。

附註:做todoList時,刪除功能可用到。

實驗

let testArr1 = ['pink', 'purple', 'green', 'white', 'skyblue']
let testArr2 = ['pink', 'purple', 'green', 'white', 'skyblue']
let testArr3 = ['pink', 'purple', 'green', 'white', 'skyblue']
let testArr4 = ['pink', 'purple', 'green', 'white', 'skyblue']
testArr1.splice(1)
testArr2.splice(1, 2)
testArr3.splice(1, 2, 'yellow')
testArr4.splice(1, 2, 'yellow', 'orange')

console.log(testArr1)
console.log(testArr2)
console.log(testArr3)
console.log(testArr4)

>> ['pink']
>> ['pink', 'white', 'skyblue']
>> ['pink', 'yellow', 'white', 'skyblue']
>> ['pink', 'yellow', 'orange', 'white', 'skyblue']

今日結語

今天整理了indexOf()find()filter()slice()splice() ,不論是在整理api回傳的資料,或是表單資料,都會經常用到,加以熟悉後在作業上相信會快很多!

IndexOf 與 find(),以及 delete()與splice(),我還想要整理它們的差異,如果有機會會補上來的。

今天就到這,如有說明不周或錯誤的地方,還請多留言討論(鞠躬)。

參考資料

filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
大部分都參考
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array


上一篇
Number常用錦集
下一篇
Object 常用錦集
系列文
前端菜雞_賀周歲成長日誌31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言