跳到主要内容

JavaScript 数组筛选

在JavaScript编程中,数组筛选是一项非常常见且实用的操作。它允许你基于特定条件从现有数组中创建一个新数组,只包含符合该条件的元素。本教程将介绍多种在JavaScript中筛选数组的方法,特别是filter()方法的使用。

什么是数组筛选?

数组筛选是指从一个数组中选择符合特定条件的元素,并创建一个包含这些元素的新数组。这在处理数据集、进行搜索功能或实现数据过滤时特别有用。

备注

筛选操作不会修改原始数组,而是创建一个新的数组。这符合JavaScript中推荐的不可变数据模式。

使用filter()方法

filter()方法是JavaScript中专门用于数组筛选的内置方法。它接收一个回调函数作为参数,该回调函数定义了筛选的条件。

基本语法

javascript
const newArray = array.filter(callback(element[, index[, array]])[, thisArg])

参数说明:

  • callback: 用于测试每个元素的函数
  • element: 当前正在处理的元素
  • index(可选): 当前元素的索引
  • array(可选): 调用filter()的数组
  • thisArg(可选): 执行callback时使用的this

简单示例

让我们从一个简单的例子开始,筛选出一个数字数组中的偶数:

javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.filter(number => number % 2 === 0);

console.log(evenNumbers); // 输出: [2, 4, 6, 8, 10]

筛选对象数组

filter()方法在处理对象数组时特别有用:

javascript
const products = [
{ name: "手机", price: 1999, inStock: true },
{ name: "笔记本电脑", price: 5999, inStock: true },
{ name: "耳机", price: 599, inStock: false },
{ name: "平板", price: 2999, inStock: true },
{ name: "相机", price: 3999, inStock: false }
];

// 筛选出有库存的产品
const availableProducts = products.filter(product => product.inStock === true);
console.log(availableProducts);
// 输出:
// [
// { name: "手机", price: 1999, inStock: true },
// { name: "笔记本电脑", price: 5999, inStock: true },
// { name: "平板", price: 2999, inStock: true }
// ]

// 筛选价格低于3000的产品
const affordableProducts = products.filter(product => product.price < 3000);
console.log(affordableProducts);
// 输出:
// [
// { name: "手机", price: 1999, inStock: true },
// { name: "耳机", price: 599, inStock: false },
// { name: "平板", price: 2999, inStock: true }
// ]

高级筛选技巧

使用多个条件

你可以在filter()方法中结合使用多个条件:

javascript
// 筛选出有库存且价格低于3000的产品
const affordableInStock = products.filter(product =>
product.inStock === true && product.price < 3000
);
console.log(affordableInStock);
// 输出:
// [
// { name: "手机", price: 1999, inStock: true },
// { name: "平板", price: 2999, inStock: true }
// ]

使用外部变量进行筛选

筛选条件可以来自外部变量,这在创建动态筛选功能时很有用:

javascript
const maxPrice = 4000;
const keyword = "机";

const searchResults = products.filter(product =>
product.price <= maxPrice && product.name.includes(keyword)
);
console.log(searchResults);
// 输出:
// [
// { name: "手机", price: 1999, inStock: true },
// { name: "相机", price: 3999, inStock: false }
// ]

结合使用filter()和其他数组方法

filter()常与其他数组方法如map()sort()reduce()结合使用,创建强大的数据处理管道:

javascript
// 筛选出有库存的产品,然后按价格排序
const availableSorted = products
.filter(product => product.inStock)
.sort((a, b) => a.price - b.price);

console.log(availableSorted);
// 输出:
// [
// { name: "手机", price: 1999, inStock: true },
// { name: "平板", price: 2999, inStock: true },
// { name: "笔记本电脑", price: 5999, inStock: true }
// ]

filter()方法的替代方案

虽然filter()方法通常是数组筛选的最佳选择,但了解其他方法也很有帮助。

使用for循环

在不支持filter()的环境中,可以使用传统的for循环来筛选数组:

javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = [];

for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
evenNumbers.push(numbers[i]);
}
}

console.log(evenNumbers); // 输出: [2, 4, 6, 8, 10]

使用reduce()方法

reduce()方法也可以用于数组筛选,虽然不如filter()直观:

javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.reduce((filtered, number) => {
if (number % 2 === 0) {
filtered.push(number);
}
return filtered;
}, []);

console.log(evenNumbers); // 输出: [2, 4, 6, 8, 10]

实际应用案例

案例1:电子商务产品过滤

想象一个电子商务网站,用户可以根据多个条件筛选产品:

javascript
const allProducts = [
{ id: 1, name: "iPhone 13", category: "电子产品", price: 6999, rating: 4.8, stock: 50 },
{ id: 2, name: "MacBook Pro", category: "电子产品", price: 12999, rating: 4.9, stock: 20 },
{ id: 3, name: "咖啡杯", category: "家居", price: 39, rating: 4.3, stock: 200 },
{ id: 4, name: "运动鞋", category: "服装", price: 499, rating: 4.5, stock: 30 },
{ id: 5, name: "iPad", category: "电子产品", price: 3999, rating: 4.7, stock: 0 },
{ id: 6, name: "T恤", category: "服装", price: 99, rating: 4.2, stock: 150 }
];

// 用户筛选条件
function filterProducts(products, filters) {
return products.filter(product => {
// 类别筛选
if (filters.category && product.category !== filters.category) {
return false;
}

// 价格范围筛选
if (filters.minPrice && product.price < filters.minPrice) {
return false;
}

if (filters.maxPrice && product.price > filters.maxPrice) {
return false;
}

// 评分筛选
if (filters.minRating && product.rating < filters.minRating) {
return false;
}

// 库存筛选
if (filters.inStock && product.stock <= 0) {
return false;
}

return true;
});
}

// 使用筛选函数
const userFilters = {
category: "电子产品",
minPrice: 3000,
maxPrice: 10000,
minRating: 4.5,
inStock: true
};

const filteredProducts = filterProducts(allProducts, userFilters);
console.log(filteredProducts);
// 输出:
// [
// { id: 1, name: "iPhone 13", category: "电子产品", price: 6999, rating: 4.8, stock: 50 }
// ]

案例2:任务管理器

一个任务管理应用需要按不同条件筛选任务:

javascript
const tasks = [
{ id: 1, title: 完成JavaScript教程, priority: "高", status: "进行中", dueDate: "2023-05-15" },
{ id: 2, title: 购买日用品, priority: "低", status: "已完成", dueDate: "2023-05-10" },
{ id: 3, title: 准备演讲, priority: "高", status: "未开始", dueDate: "2023-05-20" },
{ id: 4, title: 安排会议, priority: "中", status: "进行中", dueDate: "2023-05-12" },
{ id: 5, title: 提交报告, priority: "高", status: "已完成", dueDate: "2023-05-08" }
];

// 筛选高优先级但未完成的任务
const urgentTasks = tasks.filter(task =>
task.priority === "高" && task.status !== "已完成"
);
console.log(urgentTasks);

// 筛选今天到期的任务(假设今天是2023-05-15)
const today = "2023-05-15";
const dueTodayTasks = tasks.filter(task => task.dueDate === today);
console.log(dueTodayTasks);

// 按状态分组任务
const tasksByStatus = {
inProgress: tasks.filter(task => task.status === "进行中"),
completed: tasks.filter(task => task.status === "已完成"),
notStarted: tasks.filter(task => task.status === "未开始")
};
console.log(tasksByStatus);

性能考虑

在处理大型数组时,筛选操作可能会影响性能。以下是一些优化提示:

  1. 如果可能,在数组很大时,考虑使用早期返回或中断筛选循环
  2. 对于复杂的过滤操作,考虑使用索引结构或缓存结果
  3. 在适当情况下,考虑使用第三方库(如Lodash)的优化方法

总结

JavaScript的数组筛选,特别是通过filter()方法,是一种强大的数据处理技术。它允许你:

  • 从数组中提取符合特定条件的元素
  • 基于单个或多个条件进行筛选
  • 处理简单值或复杂对象数组
  • 创建动态筛选功能
  • 与其他数组方法组合使用

掌握数组筛选是成为高效JavaScript开发者的关键技能之一。

练习

  1. 创建一个函数,筛选出数组中的所有正数
  2. 给定一个字符串数组,筛选出长度大于5的字符串
  3. 基于用户输入的最小和最大值,筛选出一个数字数组中在该范围内的数字
  4. 给定一个对象数组,每个对象代表一个人,包含姓名、年龄和职业,筛选出年龄大于30且职业是"开发者"的人
  5. 实现一个搜索函数,可以根据关键词在对象数组的多个属性中进行搜索
提示

学习编程的最好方法是实践!尝试解决这些练习,并在实际项目中应用数组筛选技术。