如何编写支持任意参数的对象数组过滤函数,筛选符合全条件的字符名称
解决字符数组多条件筛选问题
原代码问题说明
你写的isThere函数逻辑有两个核心问题:
- 四个
if是独立判断——只要字符满足其中一个条件就会被添加到结果数组,而不是要求同时满足所有传入的有效条件 - 没有处理
undefined参数的情况,比如传入undefined作为element时,char.element === undefined不会匹配任何字符,但其他条件的匹配结果还是会被累加,导致结果重复且不符合预期
最优解决方案:用对象传递筛选条件
推荐直接用对象作为筛选参数,这种方式更灵活,不需要固定参数顺序,还能轻松支持任意数量的筛选条件(后续扩展字符属性也能直接复用)。结合Array.filter()和Object.entries()实现逻辑:
const characters = [ { bodyType: "tall", element: "air", gender: "female", name: "Renna", weapon: "sword", }, { bodyType: "tall", element: "fire", gender: "male", name: "Igneus", weapon: "sword", }, { bodyType: "medium", element: "water", gender: "male", name: "Dagon", weapon: "spear", }, ]; function filterCharacters(filters) { // 筛选出满足所有传入条件的字符 const matched = characters.filter(char => { // 遍历所有筛选条件,确保字符每一项都匹配 return Object.entries(filters).every(([key, value]) => char[key] === value); }); // 提取字符名称返回 return matched.map(char => char.name); } // 调用示例 console.log(filterCharacters({ bodyType: "tall", gender: "male" })); // 输出: ['Igneus'] console.log(filterCharacters({ weapon: "sword" })); // 输出: ["Renna", "Igneus"] console.log(filterCharacters({ element: "water", gender: "male" })); // 输出: ['Dagon']
方案优势
- 灵活度高:想传几个条件就传几个,不用管顺序,后续加新属性也不用改函数
- 逻辑严谨:
every()方法确保字符必须满足所有传入的筛选条件 - 自动去重:每个符合条件的字符只会被筛选一次,不会出现重复结果
兼容原参数格式的修改(可选)
如果一定要保留原函数的参数顺序,可以先把非undefined的参数转换成筛选对象,再用同样的逻辑处理:
function isThere(bodyType, element, gender, weapon) { // 只保留非undefined的筛选条件 const filters = {}; if (bodyType) filters.bodyType = bodyType; if (element) filters.element = element; if (gender) filters.gender = gender; if (weapon) filters.weapon = weapon; return characters .filter(char => Object.entries(filters).every(([k, v]) => char[k] === v)) .map(char => char.name); } // 调用示例 console.log(isThere("tall", undefined, "male", undefined)); // 输出: ['Igneus'] console.log(isThere(undefined, undefined, undefined, "sword")); // 输出: ["Renna", "Igneus"]
内容的提问来源于stack exchange,提问作者Raziel
相关产品推荐
相关产品推荐

