如何实现基于多输入值的通用对象数组过滤?
通用多关键词协同过滤实现(无需指定属性)
要实现这种无需指定属性的通用多关键词协同过滤,核心思路是将输入拆分为独立关键词,再验证每个关键词是否能匹配目标对象的某个属性值(统一处理大小写避免匹配误差)。以下是简洁的可复用实现:
核心过滤函数
function filterItems(items, input, options = { caseSensitive: false, exactMatch: true }) { const { caseSensitive, exactMatch } = options; // 拆分输入为非空关键词数组 const keywords = input.trim().split(/\s+/).filter(Boolean); // 空输入直接返回全部数据 if (keywords.length === 0) return [...items]; return items.filter(item => { // 提取对象所有属性值,统一大小写(仅针对字符串类型) const processedValues = Object.values(item).map(val => { if (typeof val !== 'string') return val; return caseSensitive ? val : val.toLowerCase(); }); // 验证每个关键词是否都能匹配到某个属性值 return keywords.every(keyword => { const targetKeyword = caseSensitive ? keyword : keyword.toLowerCase(); return processedValues.some(val => { if (typeof val !== 'string') return false; return exactMatch ? val === targetKeyword : val.includes(targetKeyword); }); }); }); }
配置参数说明
caseSensitive: 布尔值,是否区分大小写,默认false(不区分)exactMatch: 布尔值,是否精确匹配属性值,默认true(完全一致才匹配;设为false时支持模糊包含,比如输入"Red"会匹配"Redish")
测试示例
1. 服装数据过滤
const clothes = [ { color: "red", clothingType: "shirt" }, { color: "red", clothingType: "scarf" }, { color: "blue", clothingType: "shirt" }, { color: "green", clothingType: "pants" } ]; // 输入"Red Shirt",仅返回匹配的条目 console.log(filterItems(clothes, "Red Shirt")); // 输出: [{ color: "red", clothingType: "shirt" }]
2. 用户数据过滤
const users = [ { firstName: "John", lastName: "Smith" }, { firstName: "John", lastName: "Doe" }, { firstName: "Jane", lastName: "Smith" } ]; // 输入"John Smith",仅返回匹配的用户 console.log(filterItems(users, "John Smith")); // 输出: [{ firstName: "John", lastName: "Smith" }]
扩展场景处理
如果需要支持关键词去重匹配(比如输入"red red"时,只要对象有一个"red"属性值就匹配),可以修改逻辑为用Set存储属性值,减少重复检查:
function filterItemsWithUniqueMatch(items, input, options = { caseSensitive: false }) { const { caseSensitive } = options; const keywords = input.trim().split(/\s+/).filter(Boolean); if (keywords.length === 0) return [...items]; return items.filter(item => { const valueSet = new Set( Object.values(item).map(val => { if (typeof val !== 'string') return val; return caseSensitive ? val : val.toLowerCase(); }) ); return keywords.every(keyword => { const target = caseSensitive ? keyword : keyword.toLowerCase(); return valueSet.has(target); }); }); }
内容的提问来源于stack exchange,提问作者Dissonant_Reality
相关产品推荐
相关产品推荐

