今天我們來繼續 Javascript 數組系列的文章,上文 《Javascript數組系列二之迭代方法1》 我們說到一些數組的迭代方法,我們在開發項目實戰的過程中熟練的使用可以大大提高我們的開發效率以及數據的處理。接下來我們繼續來講解其他的一些迭代的方法。 天也黑了,時間也不早了,話不多說,擼起袖子 ...
今天我們來繼續 Javascript 數組系列的文章,上文 《Javascript數組系列二之迭代方法1》 我們說到一些數組的迭代方法,我們在開發項目實戰的過程中熟練的使用可以大大提高我們的開發效率以及數據的處理。接下來我們繼續來講解其他的一些迭代的方法。
天也黑了,時間也不早了,話不多說,擼起袖子幹起來!
數組的迭代方法
reduce
該方法對一個累加值和數組中的每一個元素執行給定的函數,返回一個函數累計處理的結果。
乍一看定義好像不是很好理解,來看一個例子你就會立刻明白,簡單來說該方法就是對數組進行合併操作。
const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduce((sum, value) => sum + value);
console.log(result); //15
這裡值得註意的是,reduce 方法的執行順序是從左到右,為什麼特意指出,因為下麵我們會介紹一個從右到左的方法(reduceRight),先行瞭解下。
從上面的例子我們能看出「reduce」方法的作用,但是可能我們還不清楚具體的執行過程是怎麼樣的,繼續走起!
還是按照以往的慣例,我們先來看看「reduce」的參數和語法
該方法接受兩個參數,一個是元素每一項執行的回調函數;一個是可選的參數,作為第一次調用函數的初始值(也就是第一次的累加值)
傳入的回調函數會接受四個參數分別是:調用函數返回的累計值(accumulator),數組中當前處理的元素(currentValue),當前處理元素的索引(currentIndex,可選),數組本身(array,可選)。
//語法
array.reduce(callback[, initialValue])
array.reduce(callback(accumulator, currentValue, currentIndex, array){
//return 合併操作
});
參數與語法認清之後,先來看兩個例子
//例子1
const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduce((accumulator, currentValue, currentIndex) => {
console.log(currentIndex); //1, 2, 3, 4
return accumulator + currentValue;
});
console.log(result); //15
//例子2
const newResult = numbers.reduce((accumulator, currentValue, currentIndex) => {
console.log(currentIndex); //0, 1, 2, 3, 4
return accumulator + currentValue;
}, 10);
console.log(newResult); //25
從以上兩個例子中我們也看到一些不同的輸出結果,原因是因為我們給定了一個初始值之後,方法開始執行的位置發生變化,那麼是如何變化的呢?
這裡存在兩種情況:
-
如果我們在使用「reduce」方法的時候,提供可選的初始值(initialValue),在回調函數第一次執行的時候,第一次的累計值會預設取值為給定的初始值,當前參與計算的元素會從數組的第一項開始
(即:accumulator = initialValue,currentValue = array[0]) -
如果我們在使用「reduce」方法的時候,沒有提供初始值(initialValue),那麼在回調函數第一次執行的時候,第一次的累計值為數組的第一項,當前參與計算的值為數組的第二項(即: accumulator = array[0],
currentValue = array[1])
簡單來說如果我們提供初始值,回調函數會從數組的第二項(index=0)開始執行,反之回調函數會從數組的第一項開始執行(index=1),這就是上面例子中輸出索引的結果不同的原因。
說了這麼多,大家肯定很清楚了,那最後我們來看看 「reduce」 方法的相容性,還是直接上圖。
reduce支持的瀏覽器
reduceRight
從名字我們已經看出「reduceRight」與「reduce」肯定有扯不清的關係了。上面我們也說到「reduce」方法的執行順序是從左到右。
而「reduceRight」方法的執行順序為從右到左,除了在這一點上與「reduce」不同之外,其他地方與「reduce」一毛一樣,所以我們就不做過多解釋了,看一個簡單的例子即可。
const numbers = [1, 2, 3, 4, 5];
const result = numbers.reduceRight((accumulator, currentValue, currentIndex) => {
console.log(currentIndex); //3, 2, 1, 0
return accumulator + currentValue;
});
console.log(result); //15
find
該方法對數組的每一個元素執行給定的函數,返回滿足條件的元素,如果發現滿足條件的值會立即返回當前元素,如果未發現滿足條件的元素則返回 undefined。
該方法接受兩個參數,一個是元素每一項執行的回調函數,一個是可選參數,回調函數運行時 this 的值。
傳入的回調函數會接受三個參數分別是:數組中的元素(item),元素的索引(index,可選),數組本身(array,可選)。
//語法
array.find(callback[, this])
array.find(callback(item, index, array){
//return 執行的操作
});
//例子
const numbers = [4, 9, 16, 25, 29];
const result = numbers.find((item, index)=> {
console.log(index); //0, 1, 2
return item > 10;
});
console.log(result); //16
根據案例中列印的結果與最後返回的結果來看,當找到滿足條件的元素時會立刻返回結果,並終止函數的執行。可以理解為「find」方法就是在眾多數據中找到一個我們想要的。
讓我們來看看 「find」方法的相容性,繼續直接上圖。
find支持的瀏覽器
findIndex
通過「find」方法聰明的你們肯定會發現「findIndex」用法。
是的「findIndex」的用法與 「find」基本相同,不同的是「findIndex」返回的是我們滿足條件元素的索引,而「find」返回的是元素。
既然如此我們就不做過多介紹,還是利用我們在「find」方法中使用的案例。
//例子
const numbers = [4, 9, 16, 25, 29];
const result = numbers.findIndex((item)=> {
return item > 10;
});
console.log(result); //2
雖說兩者的用法基本相同,但是在沒有得到滿足我們條件的元素時,其兩者返回的結果會略有不同。一個返回 undefined,一個返回 -1。
const numbers = [4, 9, 16, 25, 29];
const result = numbers.find((item)=> {
return item > 30;
});
console.log(result); //undefined
const resultIndex = numbers.findIndex((item)=> {
return item > 30;
});
console.log(resultIndex); //-1
indexOf
該方法會對給定的一個值在數組中進行查找,如果找到相同的元素則返回元素的索引,否則返回 -1 。
該方法接受兩個參數:一個是要查找的元素(searchElement),一個是查找開始的位置(fromIndex,可選),預設值為 0 。
//語法
arr.indexOf(searchElement)
arr.indexOf(searchElement[, fromIndex = 0])
//案例
const numbers = [2, 3, 2, 4, 2];
console.log(numbers.indexOf(2)); //0
console.log(numbers.indexOf('2')); //-1
console.log(numbers.indexOf(2, 1)); //2
console.log(numbers.indexOf(2, -1)); //4
「indexOf」方法有幾點需要我們註意的地方。
- 在方法執行查找的過程中使用的是嚴格相等(===),案例中查找 '2' 時返回 -1 ,就是這個原因,如果不知道 == 與 === 有什麼區別的小伙伴可以自己查閱下資料進行瞭解。
- 關於第二個參數 fromIndex,如果當 fromIndex 的數值大於或者等於執行的數組長度時,就會返回 -1,因為沒有地方查找了。如果查找的數值為負數,則會從數組的後面開始查找。
- 要註意的是數組的末尾的索引是從 -1 開始的;例如:-1從數組的最後一個元素開始,-2從數組的倒數第二個元素開始。
- 非常重要的一點是不管 fromIndex 的數值為正數還是負數「indexOf」方法的查找順序都是從前向後執行的,案例中最後一個方法輸出的是 4 而不是 2 的原因。
那有沒有從後向前查找元素的方法呢?答案是肯定的,後面我們會繼續說的,在這之前我們先來看一個我們在項目開發過程中經常使用的一個例子。
我們就利用上面說到的 reduce 與 indexOf 來實現一個數組簡單去重的方法
const numbers = [2, 3, 2, 4, 2, 3, 1, 4];
const result = numbers.reduce((prev, current) => {
if (prev.indexOf(current) === -1) {
prev.push(current);
}
return prev;
}, []);
console.log(result); //[2, 3, 4, 1]
最後我們再來看看「indexOf」方法的相容性。
相容圖表
lastIndexOf
「lastIndexOf」與「indexOf」用法相同;不同的是前者
是從後向前查找,後者是從前向後查找。
const numbers = [2, 3, 2, 4, 2];
console.log(numbers.lastIndexOf(2)); //4
console.log(numbers.lastIndexOf('2')); //-1
console.log(numbers.lastIndexOf(2, 1)); //0
console.log(numbers.lastIndexOf(2, -1)); //4
總結
我們花了兩篇文章說了數組的一系列迭代方法,其實包括 forEach、map、filter、find、reduce等等,從中我們可以看出數組在 Javascript 中的地位,同時數組在我們實際的項目中也扮演著重要的地位。如果文章你喜歡,可以繼續關註,後面我們還會說到數組的其他一些操作方法也同樣有著很重要的作用。