介绍一下.filter
字面上可以用来根据条件过滤数组元素的方法,除了.length
属性之外,我们还可以用它来对数组的某些元素进行计数。函数提供.filter
方法的条件,作为参数传递。
此外,我们将介绍.reduce
为数组中的每个元素执行一个函数并返回单个值的方法。
作为参数传递的函数可以是箭头函数,也可以是作为回调函数的普通函数。它将指示将哪些元素.filter
添加到返回的数组或该.reduce
方法将对数组中的每个元素执行什么操作。
1.在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()
函数接收 anelement
作为参数,如果它element
等于某个值,在本例中为'one'
,则返回true
,否则返回false
。
因此,该.filter
方法添加element
了条件导致的任何内容true
;由于原始数组只有第一个元素 as one
,因此.filter
仅返回一个元素。
请注意,该condition()
函数是在.filter
方法内部声明的。如果您在外部声明它并在 内部调用它filter
,它将不起作用,因为element
是回调范围的一部分。
回调函数作为参数传递给另一个名为outer function
.
外层函数会调用回调函数做一些事情;在.filter
方法的情况下,它将调用condition()
回调函数以根据条件过滤数组。
回到我们的目标,.filter
will 最终会返回一个新的数组,其中包含一个array.length
元素,每个元素都是一个元素,其回调函数返回的值等同于true
。我们可以很容易地使用属性.length计算这些过滤后的元素。
是数组实体的.length
一个属性,它返回数组中元素的数量。该数字始终大于该数组中的最高索引,因为第一个元素始终位于索引 equals 上0
。
// Input
let array = [1, 2, 3, 4, 5]
console.log(array.length)
输出:
// Output
5
中的元素个数为 5。5array
大于 value 的索引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
中所有 15 个音符中的音符数是否大于 7 。notes
2.使用.reduce方法在JavaScript 中执行回调函数
我们可以使用.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
在第一次迭代中将其视为数组的第一个元素。
但是如果我们要对数组中的某些元素进行计数呢?我们不能将第一个元素用作 the,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
,因为我们不传递回调函数之外的任何其他参数。
要进行更正,我们可以将 a0
作为第二个.reduce
参数传递:
// Input
let array = [1, 2, 3, 4, 5].reduce((sum, value) => (value == 2 ? sum + 1 : sum), 0)
console.log(array)
输出:
// Output
1
这样,.reduce
每次sum + 1
当前元素等于 2 时,都会使用 进行sum
初始化0
。
3.使用.prototype数组实体在JavaScript中编写自定义方法或属性
.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