JavaScript如何筛选对象,保留val含'A'且val值唯一的属性
需求回顾
需要对输入对象做筛选返回新对象,筛选规则为:
- 仅保留
val字段包含字符"A"的条目 - 相同
val值的条目只保留第一次出现的id项
期望输出结果:
{ "id1": { "val": "AAA" }, "id4": { "val": "ABC" } }
现有实现问题
你当前通过拼接字符串+indexOf记录已匹配值的写法存在两个明显问题:
- 匹配准确性差:如果
val本身包含空格,会出现误判。比如已拼接字符串里存了"AB C",新条目val为"AB"时,indexOf会错误返回匹配成功 - 性能偏低:字符串
indexOf是逐字符线性扫描,随着已记录值增多,匹配耗时会持续上升
优化实现
用ES6的Set结构存储已出现的val值,Set的has查询是O(1)时间复杂度,且为精确值匹配,不会出现字符串匹配的误判问题:
const obj = { id1: { val: 'AAA' }, id2: { val: 'BBB' }, id3: { val: 'AAA' }, id4: { val: 'ABC' }, }; const filteredObj = {}; const existedValues = new Set(); for (const key in obj) { const currentVal = obj[key].val; if (currentVal.includes('A') && !existedValues.has(currentVal)) { filteredObj[key] = obj[key]; existedValues.add(currentVal); } } console.log(filteredObj);
如果习惯函数式编程风格,也可以用Object.entries配合reduce实现,运行效率和循环写法基本一致:
const existedValues = new Set(); const filteredObj = Object.entries(obj).reduce((res, [id, item]) => { if (item.val.includes('A') && !existedValues.has(item.val)) { existedValues.add(item.val); res[id] = item; } return res; }, {});
优化细节:如果实际数据中不含"A"的条目占比很高,可以把
val包含"A"的判断放在前面,提前过滤不符合要求的条目,减少后续Set查询的次数,进一步提升运行速度。
内容的提问来源于stack exchange,提问作者thdoan
相关产品推荐
相关产品推荐

