在 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