在上节,我们学习如何使用 JavaScript Array sort() 方法对数字、字符串和对象的分类示例,错过的小伙伴可以点击文章《【JavaScript 教程】第六章 数组10— sort() : 对数组中的元素进行排序》进行学习。

那么,在今天的教程中,我们一起来学习如何使用 JavaScript Array filter() 方法过滤数组中的元素。

JavaScript 数组 filter() 方法介绍

使用数组时最常见的任务之一是创建一个包含原始数组元素子集的新数组。

假设您有一个城市对象数组,其中每个对象包含两个属性:name和population。




let cities = [
    {name: 'Los Angeles', population: 3792621},
    {name: 'New York', population: 8175133},
    {name: 'Chicago', population: 2695598},
    {name: 'Houston', population: 2099451},
    {name: 'Philadelphia', population: 1526006}
];



要查找人口超过 300 万的城市,通常使用 for 循环遍历数组元素并测试 population 属性的值是否满足条件,如下所示:




let bigCities = [];
for (let i = 0; i < cities.length; i++) {
    if (cities[i].population > 3000000) {
        bigCities.push(cities[i]);
    }
}
console.log(bigCities);



输出:




[
  { name: 'Los Angeles', population: 3792621 },
  { name: 'New York', population: 8175133 }
]



JavaScript Array 提供了 filter() 方法,允许您以更短、更简洁的方式完成此任务。

以下示例返回与上述示例相同的结果:




let bigCities = cities.filter(function (e) {
    return e.population > 3000000;
});
console.log(bigCities);



在本例中,我们调用了城市数组对象的 filter() 方法,并将其传递给一个测试每个元素的函数。

在函数内部,我们检查了数组中每个城市的人口是否大于 300 万。

如果是这种情况,则函数返回true;否则,它返回 false。如果元素满足我们传入的函数中的测试,则 filter() 方法仅包含结果数组中的元素。

在 ES6 中,使用箭头函数 (=>) 会更加简洁。




let bigCities = cities.filter(city => city.population > 3000000);
console.log(bigCities);



JavaScript Array filter() 方法详解

下面说明了 filter() 方法的语法:




arrayObject.filter(callback, contextObject);



filter() 方法创建一个新数组,其中包含所有通过 callback() 函数实现的测试的元素。

在内部,filter() 方法遍历数组的每个元素并将每个元素传递给回调函数。如果回调函数返回 true,则它将元素包含在返回数组中。

filter() 方法接受两个命名参数:回调函数和可选对象。

与Array对象的其他迭代方法如every()、some()、map()和forEach()一样,回调函数有如下形式:




function callback(currentElement, index, array){
   // ...
}



回调函数接受三个参数:

  • currentElement 参数是回调函数正在处理的数组中的当前元素。
  • 回调函数正在处理的 currentElement 的索引。
  • 被遍历的数组对象。

索引和数组参数是可选的。

filter() 方法的 contexObject 参数是可选的。如果传递 this 值,则可以在回调函数中使用 this 关键字来引用它。

需要注意的是 filter() 方法不会改变原始数组。

更多 JavaScript Array filter() 方法示例

因为 filter() 方法返回一个新数组,所以您可以将结果与其他迭代方法(例如 sort() 和 map() )链接起来。

例如,以下说明如何链接三个方法:filter()、sort() 和 map():




cities
    .filter(city => city.population < 3000000)
    .sort((c1, c2) => c1.population - c2.population)
    .map(city => console.log(city.name + ':' + city.population));



输出:




Philadelphia:1526006
Houston:2099451
Chicago:2695598



程序是怎么运行的。

首先,filter() 方法返回人口少于 300 万的城市。

第二、sort()方法按人口降序对得到的城市进行排序。

第三,map() 方法在 Web 控制台中显示结果数组中的每个元素。

以下示例说明了 contextObject 参数的使用,该参数指定可以在 callback() 函数中使用 this 关键字引用的对象。




function isInRange(value) {
    if (typeof value !== 'number') {
        return false;
    }
    return value >= this.lower && value <= this.upper;
}


let data = [10, 20, "30", 1, 5, 'JavaScript filter', undefined, 'example'];


let range = {
    lower: 1,
    upper: 10
};


let numberInRange = data.filter(isInRange, range);


console.log(numberInRange); // [10, 1, 5]



输出:




[ 10, 1, 5 ]



程序是怎么运行的。

  • 首先,定义一个isInRange()函数来检查它的参数是否是一个数字并且是否在对象的lower和upper属性指定的范围内。
  • 接下来,定义一个包含numbers、strings和undefined的混合数据数组。
  • 然后,定义range具有两个属性的对象lower和upper。
  • 之后,调用数组的filter()方法data并传入isInRange()函数和range 对象。因为我们传入range对象,在isInRange()函数内部,this关键字引用range对象。
  • 最后,在 Web 控制台中显示结果数组。

在本教程中,您已经学习了如何filter()根据回调函数提供的测试,使用 JavaScript Array方法过滤数组中的元素。

程序是怎么运行的。

  • 首先,定义 isInRange() 函数,该函数检查其参数是否为数字并且是否在对象的下限和上限属性指定的范围内。
  • 接下来,定义一个包含数字、字符串和未定义的混合数据数组。
  • 然后,使用两个属性lower 和upper 定义范围对象。
  • 之后调用数据数组的filter()方法,传入isInRange()函数和range对象。因为我们传入范围对象,在 isInRange() 函数内部, this 关键字引用了范围对象。
  • 最后,在 Web 控制台中显示结果数组。

在本教程中,我们学习了如何使用 JavaScript Array filter() 方法基于回调函数提供的测试来过滤数组中的元素。

今天的内容就到这里了。