在 JavaScript 中計算陣列的某些元素出現的次數

Pablo Felipe 2023年1月30日 2022年5月1日
  1. 在 JavaScript 中使用 .filter 方法來計數陣列中的某些元素
  2. 在 JavaScript 中使用 .reduce 方法執行回撥函式
  3. 在 JavaScript 中使用 .prototype 陣列實體編寫自定義方法或屬性
在 JavaScript 中計算陣列的某些元素出現的次數

介紹一下 .filter 方法,該方法可用於根據條件過濾陣列元素,除了 .length 屬性外,我們還可以使用它來計算陣列的某些元素。函式提供 .filter 方法的條件,作為引數傳遞。

此外,我們將介紹 .reduce 方法,該方法為陣列中的每個元素執行一個函式並返回一個值。

作為引數傳遞的函式可以是箭頭函式,也可以是作為回撥函式的普通函式。它將指示 .filter 將新增到返回陣列中的元素或 .reduce 方法將對陣列中的每個元素執行什麼操作。

在 JavaScript 中使用 .filter 方法來計數陣列中的某些元素

.filterArray 實體的一個方法,它返回一個由提供的條件過濾的新陣列。返回一個新陣列意味著呼叫該方法的原始陣列將保持不變。

例如,如果我們想要陣列中所有等於值 one 的元素,我們可以使用 .filter,如下所示:

// Input
let array = ['one', 'two', 'three', 'four', 'five']
array = array.filter(element => element == 'one')
console.log(array)

輸出:

// Output
[ 'one' ]

正如預期的那樣,.filter 方法返回了一個基於 element == 'one' 條件的陣列。因此,如果陣列的實際元素等於'one',則過濾器會將這個元素新增到返回的陣列中。

但是 .filter 方法內部發生了什麼?通過對 condition() 函式使用通用函式結構,我們可以看得更清楚:

// Input
let array = ['one', 'two', 'three', 'four', 'five']
array = array.filter(function condition(element) {
    if (element == 'one') return true
    return false
})
console.log(array)

有了這個,我們有相同的第一個示例輸出:

// Output
[ 'one' ]

condition() 函式接收一個 element 作為引數,如果此 element 等於某個值,在本例中為 'one',則返回 true,否則返回錯誤的

因此,.filter 方法新增條件導致 true 的任何元素;由於原始陣列只有第一個元素為 one,因此 .filter 僅返回一個元素。

請注意,condition() 函式是在 .filter 方法中宣告的。如果你在外面宣告它並在 filter 中呼叫它,它不會起作用,因為 element 是回撥範圍的一部分。

回撥函式作為引數傳遞給另一個稱為外部函式的函式。

外層函式會呼叫回撥函式做某事;在 .filter 方法的情況下,它將呼叫 condition() 回撥函式以根據其條件過濾陣列。

回到我們的目標,.filter 最終將返回一個帶有 array.length 元素的新陣列,每個元素都是一個元素,其回撥函式返回的值等於 true。我們可以很容易地使用 .length 屬性來計算這些過濾後的元素。

.length 是陣列實體的一個屬性,它返回陣列中元素的數量。這個數字總是大於該陣列中的最高索引,因為第一個元素總是在索引上等於 0

// Input
let array = [1, 2, 3, 4, 5]
console.log(array.length)

輸出:

// Output
5

array 中的元素數為 5。5 大於值 5 的索引,即 4。

綜上所述,作為一個例子,我們可以使用以下內容:如何獲得大於七的學校的所有測試筆記的數量?測試筆記的陣列在示例中。

// Input
let notes = [7.0, 6.7, 7.3, 9.8, 5.6, 7.1, 7.8, 6.2, 8.0, 9.0, 4.5, 6.9, 7.5, 8.5, 6.4]
greaterThanSeven = notes.filter(value => value > 7)
console.log(greaterThanSeven.length)

輸出:

// Output (The array returned by the .filter is: [7.3, 9.8, 7.1, 7.8, 8, 9, 7.5, 8.5])
8

因此,8 是原始 notes 陣列中所有 15 個音符中大於 7 的音符數。

在 JavaScript 中使用 .reduce 方法執行回撥函式

我們可以使用 .reduce 陣列實體方法作為另一種選擇。此方法用於對每個陣列元素執行回撥函式(和 .filter),但最終會返回一個值。

.reduce 工作的一個簡單示例是陣列中所有元素的總和:

// Input
let array = [1, 2, 3, 4, 5].reduce((previous, current) => previous + current)
console.log(array)

輸出:

// Output
15

但是我們可以通過傳遞初始值以另一種方式使用此方法。在前面的例子中,我們可以看到 previous 從陣列中的第一個索引元素開始,作為回撥函式,這樣:

/*
previous + current = result
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15 -> final result
*/

這個總和有效,因為如果我們不將第二個引數(因為回撥函式是第一個引數)傳遞給 .reduce 方法,它將在第一次迭代中將 previous 視為陣列的第一個元素。

但是如果我們想計算陣列中的某些元素呢?我們不能將第一個元素用作 previous,因為它可能導致錯誤的值。

下面的示例是關於計算陣列中有多少 2 個數字:

// Input
let array = [1, 2, 3, 4, 5].reduce((sum, value) => (value == 2 ? sum + 1 : sum))
console.log(array)

輸出:

// Output
2

如我們所見,結果是 2,但正確答案是 1。發生這種情況是因為 sum 是用第一個元素 1 初始化的,因為我們沒有傳遞迴調函式之外的任何其他引數。

為了進行更正,我們可以傳遞一個 0 作為第二個 .reduce 引數:

// Input
let array = [1, 2, 3, 4, 5].reduce((sum, value) => (value == 2 ? sum + 1 : sum), 0)
console.log(array)

輸出:

// Output
1

這樣,每次當前元素等於 2 時,.reduce 都會產生 sum + 1,而 sum 初始化為 0

在 JavaScript 中使用 .prototype 陣列實體編寫自定義方法或屬性

作為一個優點,我們可以使用 .prototype 陣列實體屬性來向該實體寫入自定義方法或屬性,而不是每次需要計算陣列中的某些元素時都使用所有這些邏輯。

要為陣列實體建立一個 .countCertainElements 方法,我們可以使用以下結構:

// Input
// Declaring the prototype .countCertainElements method
Array.prototype.countCertainElements = function(value){
    return this.filter(arrayElement => arrayElement == value).length
}
let array1 = [1, 2, 2, 2, 3, 4, 5]
console.log(array1.countCertainElements(2))

輸出:

// Output
3

我們可以對 .reduce 做同樣的事情:

// Input
// Declaring the prototype .countCertainElements method
Array.prototype.countCertainElements = function(value){
    return this.reduce((sum, element) => (element == value ? sum + 1 : sum), 0)
}
let array1 = [1, 2, 2, 2, 3, 4, 5]
console.log(array1.countCertainElements(2))

輸出:

// Output
3

相關文章 - JavaScript Array