在 JavaScript 中计算数组的某些元素出现的次数
-
在 JavaScript 中使用
.filter
方法来计数数组中的某些元素 -
在 JavaScript 中使用
.reduce
方法执行回调函数 -
在 JavaScript 中使用
.prototype
数组实体编写自定义方法或属性
介绍一下 .filter
方法,该方法可用于根据条件过滤数组元素,除了 .length
属性外,我们还可以使用它来计算数组的某些元素。函数提供 .filter
方法的条件,作为参数传递。
此外,我们将介绍 .reduce
方法,该方法为数组中的每个元素执行一个函数并返回一个值。
作为参数传递的函数可以是箭头函数,也可以是作为回调函数的普通函数。它将指示 .filter
将添加到返回数组中的元素或 .reduce
方法将对数组中的每个元素执行什么操作。
在 JavaScript 中使用 .filter
方法来计数数组中的某些元素
.filter
是 Array
实体的一个方法,它返回一个由提供的条件过滤的新数组。返回一个新数组意味着调用该方法的原始数组将保持不变。
例如,如果我们想要数组中所有等于值 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