1. 程式人生 > >Javascript陣列系列二之迭代方法2

Javascript陣列系列二之迭代方法2

今天我們來繼續 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 合併操作});

引數與語法認清之後,先來看兩個例子

//例子1const 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//例子2const newResult = numbers.reduce((accumulator, currentValue, currentIndex) => {    console.log(currentIndex);  //0, 1, 2, 3, 4    return accumulator + currentValue;}, 10);console.log(newResult); //25

從以上兩個例子中我們也看到一些不同的輸出結果,原因是因為我們給定了一個初始值之後,方法開始執行的位置發生變化,那麼是如何變化的呢?

這裡存在兩種情況:

  1. 如果我們在使用「reduce」方法的時候,提供可選的初始值(initialValue),在回撥函式第一次執行的時候,第一次的累計值會預設取值為給定的初始值,當前參與計算的元素會從陣列的第一項開始(即:accumulator = initialValue,currentValue = array[0])

  2. 如果我們在使用「reduce」方法的時候,沒有提供初始值(initialValue),那麼在回撥函式第一次執行的時候,第一次的累計值為陣列的第一項,當前參與計算的值為陣列的第二項(即: accumulator = array[0],currentValue = array[1])

簡單來說如果我們提供初始值,回撥函式會從陣列的第二項(index=0)開始執行,反之回撥函式會從陣列的第一項開始執行(index=1),這就是上面例子中輸出索引的結果不同的原因。

說了這麼多,大家肯定很清楚了,那最後我們來看看 「reduce」 方法的相容性,還是直接上圖。

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支援的瀏覽器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); //undefinedconst 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)); //0console.log(numbers.indexOf('2')); //-1console.log(numbers.indexOf(2, 1)); //2console.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)); //4console.log(numbers.lastIndexOf('2')); //-1console.log(numbers.lastIndexOf(2, 1)); //0console.log(numbers.lastIndexOf(2, -1)); //4

總結

我們花了兩篇文章說了陣列的一系列迭代方法,其實包括 forEach、map、filter、find、reduce等等,從中我們可以看出陣列在 Javascript 中的地位,同時陣列在我們實際的專案中也扮演著重要的地位。如果文章你喜歡,可以繼續關注,後面我們還會說到陣列的其他一些操作方法也同樣有著很重要的作用。