如何在JavaScript中基于多个值过滤数组?React前端筛选实现问题
JavaScript/React 多条件数组过滤实现方案
核心过滤逻辑
你需要的是多条件且关系过滤:空筛选条件自动跳过校验,所有非空筛选条件都匹配的条目才会被返回,姓名搜索做模糊匹配,下拉字段做精确匹配。
核心过滤函数代码如下:
// filters 是存储所有筛选条件的对象,格式为 {name: '', group: '', house: '', subject: ''} const getFilteredData = (originalData, filters) => { return originalData.filter(item => { // 遍历所有筛选条件,全部满足才返回true return Object.entries(filters).every(([filterKey, filterValue]) => { // 筛选值为空时直接通过校验 if (!filterValue) return true // 姓名字段做大小写不敏感的模糊搜索 if (filterKey === 'name') { return item[filterKey].toLowerCase().includes(filterValue.toLowerCase()) } // 下拉选择字段做精确匹配 return item[filterKey] === filterValue }) }) }
React 完整实现示例
下面是包含搜索框、下拉选择和结果渲染的完整组件代码:
import { useState } from 'react' // 原始数据 const originalData = [ { name: "anna", group: "group 1", house: "green", subject: "math" }, { name: "mike", group: "group 2", house: "blue", subject: "science" }, { name: "mike", group: "group 2", house: "blue", subject: "physics" }, { name: "holly", group: "group 1", house: "green", subject: "chemistry" } ] export default function MultiFilterDemo() { // 筛选条件状态,空值代表未选择该条件 const [filters, setFilters] = useState({ name: '', group: '', house: '', subject: '' }) // 统一处理筛选条件变更 const handleFilterChange = (e) => { const { name, value } = e.target setFilters(prev => ({ ...prev, [name]: value })) } // 实时计算过滤后的数据 const filteredData = getFilteredData(originalData, filters) // 自动提取下拉可选值,也可以根据业务需求手动定义 const groupOptions = [...new Set(originalData.map(item => item.group))] const houseOptions = [...new Set(originalData.map(item => item.house))] const subjectOptions = [...new Set(originalData.map(item => item.subject))] return ( <div style={{ padding: '24px' }}> {/* 筛选操作区 */} <div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', marginBottom: '24px' }}> <input type="text" name="name" placeholder="搜索姓名" value={filters.name} onChange={handleFilterChange} style={{ padding: '6px 8px' }} /> <select name="group" value={filters.group} onChange={handleFilterChange} style={{ padding: '6px 8px' }} > <option value="">全部分组</option> {groupOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)} </select> <select name="house" value={filters.house} onChange={handleFilterChange} style={{ padding: '6px 8px' }} > <option value="">全部学院</option> {houseOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)} </select> <select name="subject" value={filters.subject} onChange={handleFilterChange} style={{ padding: '6px 8px' }} > <option value="">全部科目</option> {subjectOptions.map(opt => <option key={opt} value={opt}>{opt}</option>)} </select> </div> {/* 结果展示区 */} <h3>筛选结果</h3> <pre style={{ background: '#f5f5f5', padding: '12px', borderRadius: '4px' }}> {JSON.stringify(filteredData, null, 2)} </pre> </div> ) }
方案特性
- 完全匹配需求:无筛选条件时返回全部原始数据,多条件同时满足才返回对应条目
- 扩展性强:后续新增筛选字段只需要在
filters状态中新增对应key,添加对应的输入组件即可,无需修改过滤逻辑 - 搜索体验优化:姓名搜索支持大小写不敏感匹配,无需用户完全输入大小写一致的内容
内容的提问来源于stack exchange,提问作者Shreyas Chorge
相关产品推荐
相关产品推荐

