1. 50个filter工具函数全景解析
在数据处理领域,filter操作就像厨房里的筛子,帮我们从庞杂的数据原料中精准分离出需要的部分。作为前端工程必备技能,filter相关的工具函数覆盖了数组操作、对象处理、表单验证等高频场景。本文整理的50个公共函数均经过Vue3、React等主流框架实战检验,包含ES6+特性实现和兼容性方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心函数分类与实现
2.1 基础数组过滤
javascript复制// 1. 简单值过滤
const filterByValue = (arr, value) => arr.filter(item => item === value)
// 2. 多条件AND过滤(实战常用)
const multiFilter = (arr, conditions) => {
return arr.filter(item => {
return Object.entries(conditions).every(([key, val]) => {
return item[key] === val
})
})
}
// 3. 范围过滤(适合价格/日期筛选)
const rangeFilter = (arr, key, min, max) => {
return arr.filter(item => item[key] >= min && item[key] <= max)
}
注意事项:当处理10万级以上数据时,建议先用
new Set()去重再过滤,性能可提升40%左右
2.2 对象属性过滤
javascript复制// 4. 保留指定属性(适合API响应精简)
const filterProps = (obj, keys) => {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => keys.includes(key))
)
}
// 5. 深度过滤空值(处理表单数据特别有用)
const deepFilterEmpty = obj => {
return Object.entries(obj).reduce((acc, [key, val]) => {
if (val !== null && val !== undefined && val !== '') {
acc[key] = typeof val === 'object' ? deepFilterEmpty(val) : val
}
return acc
}, {})
}
2.3 特殊场景处理
2.3.1 表单验证相关
javascript复制// 6. 表单规则动态生成器
const createFormRules = fields => {
return fields.reduce((rules, field) => {
rules[field] = [
{
validator: (_, val) =>
Array.isArray(val) ? val.length > 0 : !!val.trim(),
trigger: 'blur'
}
]
return rules
}, {})
}
2.3.2 树形数据过滤
javascript复制// 7. 递归过滤树结构(菜单权限场景)
const filterTree = (tree, predicate) => {
return tree.map(node => ({ ...node }))
.filter(node => {
node.children = node.children && filterTree(node.children, predicate)
return predicate(node) || (node.children && node.children.length)
})
}
3. 性能优化方案
3.1 大数据量处理
javascript复制// 8. 分页过滤(解决内存溢出问题)
const paginatedFilter = (arr, predicate, pageSize = 100) => {
const result = []
for (let i = 0; i < arr.length; i += pageSize) {
const chunk = arr.slice(i, i + pageSize)
result.push(...chunk.filter(predicate))
}
return result
}
// 9. Web Worker并行过滤
const createFilterWorker = code => {
const blob = new Blob([code], { type: 'application/javascript' })
return new Worker(URL.createObjectURL(blob))
}
3.2 缓存优化
javascript复制// 10. 带缓存的过滤器
const createCachedFilter = (filterFn, keyFn = JSON.stringify) => {
const cache = new Map()
return arr => {
const key = keyFn(arr)
if (cache.has(key)) return cache.get(key)
const result = filterFn(arr)
cache.set(key, result)
return result
}
}
4. 框架集成方案
4.1 Vue3组合式函数
javascript复制// 11. 响应式数组过滤
import { computed } from 'vue'
export function useArrayFilter(arr, predicate) {
return computed(() => arr.value.filter(predicate))
}
// 12. 带去抖的搜索过滤
import { ref, watch, computed } from 'vue'
import { debounce } from 'lodash-es'
export function useSearchFilter(source, searchKeys) {
const searchTerm = ref('')
const filtered = computed(() => {
if (!searchTerm.value) return source.value
return source.value.filter(item =>
searchKeys.some(key =>
String(item[key]).toLowerCase().includes(searchTerm.value.toLowerCase())
)
)
})
const debouncedFilter = debounce(val => {
searchTerm.value = val
}, 300)
return { filtered, debouncedFilter }
}
4.2 React Hooks实现
javascript复制// 13. 记忆化过滤Hook
import { useMemo } from 'react'
export function useFilter(data, predicate, deps = []) {
return useMemo(() => {
return data.filter(predicate)
}, [data, ...deps])
}
// 14. 带状态管理的过滤器
import { useState, useMemo } from 'react'
export function useFilterWithState(initialData) {
const [filters, setFilters] = useState({})
const [data] = useState(initialData)
const filteredData = useMemo(() => {
return Object.entries(filters).reduce((result, [key, fn]) => {
return result.filter(item => fn(item[key]))
}, data)
}, [data, filters])
return { filteredData, setFilters }
}
5. 类型安全方案
5.1 TypeScript类型守卫
typescript复制// 15. 类型收窄过滤器
function isStringArray(arr: unknown[]): arr is string[] {
return arr.every(item => typeof item === 'string')
}
// 16. 带类型谓词的过滤
function filterByType<T>(arr: any[], typeGuard: (item: any) => item is T): T[] {
return arr.filter(typeGuard)
}
5.2 复杂类型推断
typescript复制// 17. 多类型联合过滤
type User = { type: 'user'; name: string }
type Admin = { type: 'admin'; permissions: string[] }
type Entity = User | Admin
const filterEntities = <T extends Entity['type']>(
entities: Entity[],
type: T
): Extract<Entity, { type: T }>[] => {
return entities.filter(
(e): e is Extract<Entity, { type: T }> => e.type === type
)
}
6. 实用工具函数扩展
6.1 函数式编程组合
javascript复制// 18. 过滤器组合(类似中间件管道)
const composeFilters = (...filters) => arr => {
return filters.reduce((result, filter) => filter(result), arr)
}
// 19. 条件过滤器工厂
const createConditionalFilter = (condition, trueFilter, falseFilter) => {
return arr => condition ? trueFilter(arr) : falseFilter(arr)
}
6.2 特殊数据结构处理
javascript复制// 20. Map结构过滤
const filterMap = (map, predicate) => {
return new Map([...map].filter(([key, val]) => predicate(key, val)))
}
// 21. 二维矩阵过滤
const filterMatrix = (matrix, predicate) => {
return matrix.map(row => row.filter(predicate)).filter(row => row.length)
}
7. 边界情况处理
7.1 空值安全处理
javascript复制// 22. 空安全过滤器
const safeFilter = (arr, predicate) => {
if (!Array.isArray(arr)) return []
try {
return arr.filter(predicate)
} catch {
return []
}
}
// 23. 深度空值过滤
const deepCompact = arr => {
return arr.filter(item => {
if (Array.isArray(item)) return deepCompact(item).length
return item !== null && item !== undefined
})
}
7.2 异步数据过滤
javascript复制// 24. Promise数组过滤
async function filterAsync(arr, asyncPredicate) {
const results = await Promise.all(arr.map(asyncPredicate))
return arr.filter((_, index) => results[index])
}
// 25. 流式数据过滤
async function* filterStream(asyncIterable, predicate) {
for await (const item of asyncIterable) {
if (await predicate(item)) yield item
}
}
8. 可视化辅助工具
8.1 调试工具函数
javascript复制// 26. 带日志的过滤器
const loggedFilter = (arr, predicate, label = 'Filter') => {
console.time(label)
const result = arr.filter((item, index) => {
const keep = predicate(item, index)
console.log(`[${label}] Item ${index}:`, item, keep ? '✓' : '✗')
return keep
})
console.timeEnd(label)
return result
}
// 27. 性能分析装饰器
function withPerfMetrics(filterFn) {
return function(...args) {
const start = performance.now()
const result = filterFn.apply(this, args)
const end = performance.now()
console.log(`Filter executed in ${(end - start).toFixed(2)}ms`)
return result
}
}
9. 算法优化实现
9.1 高效去重方案
javascript复制// 28. 复合键去重(比JSON.stringify更快)
const uniqueByKeys = (arr, keys) => {
const seen = new Set()
return arr.filter(item => {
const key = keys.map(k => item[k]).join('|')
return seen.has(key) ? false : seen.add(key)
})
}
// 29. 布隆过滤器实现
class BloomFilter {
constructor(size = 1000) {
this.size = size
this.store = new Array(size).fill(false)
}
add(item) {
this.store[this.hash1(item)] = true
this.store[this.hash2(item)] = true
}
mightContain(item) {
return this.store[this.hash1(item)] &&
this.store[this.hash2(item)]
}
hash1(str) { /* ... */ }
hash2(str) { /* ... */ }
}
10. 完整工具库封装
10.1 链式调用封装
javascript复制class ArrayFilter {
constructor(data) {
this.data = data
this.filters = []
}
where(predicate) {
this.filters.push(predicate)
return this
}
execute() {
return this.filters.reduce(
(result, filter) => result.filter(filter),
this.data
)
}
}
// 使用示例
new ArrayFilter(users)
.where(u => u.age > 18)
.where(u => u.isActive)
.execute()
10.2 插件系统设计
javascript复制function createFilterSystem() {
const plugins = new Map()
return {
register(name, filterFn) {
plugins.set(name, filterFn)
},
apply(name, ...args) {
if (!plugins.has(name)) {
throw new Error(`Filter ${name} not registered`)
}
return arr => plugins.get(name)(arr, ...args)
},
pipe(names, ...args) {
return arr => {
return names.reduce((result, name) => {
return this.apply(name, ...args)(result)
}, arr)
}
}
}
}
11. 实战案例解析
11.1 电商商品筛选系统
javascript复制// 30. 多维度商品过滤器
function createProductFilter(products) {
const filters = {
byPriceRange(min, max) {
return products.filter(p => p.price >= min && p.price <= max)
},
byCategory(category) {
return products.filter(p => p.categories.includes(category))
},
byRating(minRating) {
return products.filter(p => p.rating >= minRating)
},
inStock() {
return products.filter(p => p.stock > 0)
}
}
return {
apply(...filterFns) {
return filterFns.reduce(
(result, fn) => fn(result),
products
)
},
...filters
}
}
11.2 数据分析管道
javascript复制// 31. 数据清洗管道
const dataCleaningPipeline = composeFilters(
removeOutliers(3), // 移除3个标准差外的值
fillMissingValues(), // 填充缺失值
normalizeDates(), // 日期标准化
deduplicateRecords() // 记录去重
)
// 使用示例
const cleanData = dataCleaningPipeline(rawDataset)
12. 测试与验证
12.1 单元测试工具
javascript复制// 32. 过滤器测试工具
function testFilter(filterFn, testCases) {
return testCases.every(({ input, expected }) => {
const actual = filterFn(input)
return JSON.stringify(actual) === JSON.stringify(expected)
})
}
// 示例测试用例
const filterTests = [
{
input: [1, 2, 3, 4],
predicate: x => x % 2 === 0,
expected: [2, 4]
}
]
12.2 基准测试方案
javascript复制// 33. 性能对比工具
function benchmarkFilters(filters, data, iterations = 1000) {
return filters.map(({ name, fn }) => {
const start = performance.now()
for (let i = 0; i < iterations; i++) {
fn(data)
}
const duration = performance.now() - start
return { name, duration: duration.toFixed(2) }
})
}
13. 高级函数模式
13.1 柯里化过滤器
javascript复制// 34. 柯里化过滤工厂
const curryFilter = predicate => arr => arr.filter(predicate)
// 使用示例
const filterAdults = curryFilter(person => person.age >= 18)
const adults = filterAdults(people)
13.2 高阶组件集成
javascript复制// 35. React高阶组件过滤
function withDataFilter(Component) {
return function WrappedComponent({ data, ...props }) {
const [filter, setFilter] = useState(() => () => true)
const filteredData = useMemo(() => data.filter(filter), [data, filter])
return (
<Component
{...props}
data={filteredData}
onFilterChange={setFilter}
/>
)
}
}
14. 可视化过滤技术
14.1 动态规则生成器
javascript复制// 36. 可视化规则解析器
function createRuleEngine(rules) {
const operators = {
'>': (a, b) => a > b,
'<': (a, b) => a < b,
'=': (a, b) => a === b,
includes: (a, b) => String(a).includes(b)
}
return function filterData(data) {
return data.filter(item => {
return rules.every(rule => {
const [field, op, value] = rule
return operators[op](item[field], value)
})
})
}
}
15. 安全过滤措施
15.1 XSS防护过滤
javascript复制// 37. HTML安全过滤器
const sanitizeHTML = str => {
const div = document.createElement('div')
div.textContent = str
return div.innerHTML
}
// 38. 对象属性消毒
const sanitizeObject = obj => {
return Object.entries(obj).reduce((clean, [key, val]) => {
clean[key] = typeof val === 'string' ? sanitizeHTML(val) : val
return clean
}, {})
}
16. 国际化支持
16.1 多语言过滤
javascript复制// 39. 语言敏感过滤器
function createLocaleFilter(locale) {
const collator = new Intl.Collator(locale)
return {
sort(list) {
return [...list].sort(collator.compare)
},
filterByPrefix(list, prefix) {
return list.filter(item =>
collator.compare(item.substr(0, prefix.length), prefix) === 0
)
}
}
}
17. 机器学习辅助
17.1 智能推荐过滤
javascript复制// 40. 协同过滤推荐
class Recommender {
constructor(data) {
this.userPreferences = new Map()
this.itemSimilarity = new Map()
// 初始化相似度矩阵...
}
recommendForUser(userId, filterFn) {
const preferences = this.userPreferences.get(userId) || []
const candidates = this.findSimilarItems(preferences)
return candidates.filter(filterFn)
}
}
18. 函数式编程扩展
18.1 Monadic过滤器
javascript复制// 41. Maybe Monad过滤
class Maybe {
constructor(value) {
this.value = value
}
filter(predicate) {
return this.value == null ?
this :
new Maybe(predicate(this.value) ? this.value : null)
}
}
// 42. Either Monad过滤
class Either {
constructor(left, right) {
this.left = left
this.right = right
}
filter(predicate, error) {
return this.right == null ?
this :
predicate(this.right) ?
this :
new Either(error, null)
}
}
19. 实用工具函数补遗
javascript复制// 43. 索引保留过滤
function filterWithIndex(arr, predicate) {
return arr.reduce((acc, item, index) => {
if (predicate(item, index)) {
acc.push({ item, originalIndex: index })
}
return acc
}, [])
}
// 44. 分块过滤
function chunkFilter(arr, chunkSize, predicate) {
const result = []
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize)
result.push(...chunk.filter(predicate))
}
return result
}
// 45. 权重过滤
function weightedFilter(arr, weightFn, threshold) {
return arr.filter(item => {
const weight = weightFn(item)
return weight >= threshold
})
}
// 46. 最近邻过滤
function nearestNeighborFilter(points, center, radius) {
return points.filter(point => {
const dx = point.x - center.x
const dy = point.y - center.y
return Math.sqrt(dx * dx + dy * dy) <= radius
})
}
// 47. 时间窗口过滤
function timeWindowFilter(events, start, end) {
return events.filter(event => {
const time = new Date(event.timestamp).getTime()
return time >= start.getTime() && time <= end.getTime()
})
}
// 48. 频率过滤
function frequencyFilter(items, maxFrequency) {
const countMap = new Map()
return items.filter(item => {
const count = (countMap.get(item) || 0) + 1
countMap.set(item, count)
return count <= maxFrequency
})
}
// 49. 差异过滤
function differenceFilter(arr1, arr2, compareFn = (a, b) => a === b) {
return arr1.filter(item1 =>
!arr2.some(item2 => compareFn(item1, item2))
)
}
// 50. 复合条件动态过滤
function dynamicFilter(arr, conditions) {
return arr.filter(item => {
return Object.entries(conditions).every(([key, condition]) => {
if (typeof condition === 'function') {
return condition(item[key])
}
return item[key] === condition
})
})
}
20. 工程化实践建议
- 性能敏感场景优先使用
for循环替代filter,大数据集性能差异可达5-10倍 - 类型检查:对过滤函数添加PropTypes或TypeScript类型约束
- 记忆化:对纯过滤函数使用memoization技术缓存结果
- 错误边界:始终处理可能的
null/undefined输入 - 日志追踪:关键业务过滤添加调试日志
- 单元测试覆盖:
- 空数组输入
- 非法输入处理
- 边界值条件
- 性能基准测试
21. 生态集成方案
21.1 Lodash混合使用
javascript复制// 结合lodash的链式调用
import _ from 'lodash'
function enhancedFilter(data) {
return _.chain(data)
.filter(_.matches({ status: 'active' }))
.filter(_.conforms({ age: n => n >= 18 }))
.uniqBy('id')
.value()
}
21.2 Redux中间件
javascript复制// Redux过滤中间件
const filterMiddleware = ({ getState }) => next => action => {
if (action.type === 'APPLY_FILTER') {
const { data, predicate } = action.payload
return next({
type: 'FILTER_RESULT',
payload: data.filter(predicate)
})
}
return next(action)
}
22. 调试技巧
- 断点调试:在filter回调内部设置断点观察执行过程
- 中间日志:临时插入
console.log检查过滤条件匹配情况 - 性能分析:使用Chrome DevTools的Performance面板记录过滤操作
- 可视化验证:将过滤结果渲染到界面进行视觉确认
- 单元测试:为每个过滤函数编写边界条件测试用例
23. 常见问题排查
-
过滤结果为空
- 检查predicate函数返回值类型(必须是Boolean)
- 验证数据源是否为空数组
- 确认条件逻辑是否写反(特别是包含
!操作符时)
-
性能瓶颈
- 使用
console.time定位慢速过滤函数 - 检查是否在渲染循环内创建新过滤函数
- 考虑对大数据集使用分页过滤
- 使用
-
内存泄漏
- 避免在过滤函数内创建闭包引用大对象
- 及时清理缓存过期的过滤器实例
- 使用WeakMap替代Map存储临时数据
-
TypeScript类型错误
- 确保predicate函数返回类型为
boolean - 对复杂类型使用类型谓词(type predicates)
- 考虑添加泛型参数增强类型推断
- 确保predicate函数返回类型为
24. 版本兼容方案
24.1 旧版浏览器支持
javascript复制// 兼容IE的filter polyfill
if (!Array.prototype.filter) {
Array.prototype.filter = function(fn) {
var result = []
for (var i = 0; i < this.length; i++) {
if (fn(this[i], i, this)) result.push(this[i])
}
return result
}
}
24.2 渐进增强策略
javascript复制// 功能检测实现
function safeFilter(arr, predicate) {
if (typeof Array.prototype.filter === 'function') {
return arr.filter(predicate)
}
// 回退实现
var result = []
for (var i = 0; i < arr.length; i++) {
if (predicate(arr[i], i, arr)) result.push(arr[i])
}
return result
}
25. 扩展思路
- WebAssembly加速:将性能关键过滤逻辑用Rust编写
- GPU加速:通过WebGL实现大规模并行过滤
- 持久化过滤:将过滤条件保存到IndexedDB
- 服务端过滤:对超大数据集使用GraphQL字段过滤
- 智能过滤:集成机器学习模型自动优化过滤条件
