JavaScript按cat_id去重对象数组并保留最小order值项
按指定字段分组保留最小值项的数组去重实现
问题描述
从API接口接收到如下结构的分类对象数组:
[ { cat_id: '10000844', cat_id_full: '10000844-01', order: '20', }, { cat_id: '10000844', cat_id_full: '10000844-02', order: '50', }, { cat_id: '50000844', cat_id_full: '50000844-52', order: '10', }, { cat_id: '80000844', cat_id_full: '80000844-32', order: '51', }, { cat_id: '80000844', cat_id_full: '80000844-12', order: '12', }, ]
需求为按cat_id字段对数组去重,同一cat_id分组下仅保留order值最小的项,期望返回结果如下:
[ { cat_id: '10000844', cat_id_full: '10000844-01', order: '20', }, { cat_id: '50000844', cat_id_full: '50000844-52', order: '10', }, { cat_id: '80000844', cat_id_full: '80000844-12', order: '12', }, ]
当前使用lodash的uniqBy方法编写的去重代码如下:
const uniqueCats = uniqBy(cats, 'cat_id');
该方法仅能返回遍历过程中第一个匹配到的重复项,无法满足保留同组最小order值项的需求,实现不强制要求使用lodash。
可行实现方案
无依赖原生JS实现
使用Map做分组存储,单次遍历即可完成处理,时间复杂度O(n),性能最优。遍历过程中对相同cat_id的条目比较order数值大小,始终保留更小值对应的条目,最终将Map存储的结果转为数组返回即可。
注意:接口返回的
order为字符串类型,比较前需要转为数值,否则会按字符串字典序比较出现逻辑错误(例如字符串比较时'12' < '2'结果为true,不符合数值大小预期)
const getUniqueCats = (catList) => { const catMap = new Map(); for (const item of catList) { const catId = item.cat_id; const currentOrder = Number(item.order); if (!catMap.has(catId)) { catMap.set(catId, item); continue; } const existItem = catMap.get(catId); if (currentOrder < Number(existItem.order)) { catMap.set(catId, item); } } return Array.from(catMap.values()); }; // 调用 const uniqueCats = getUniqueCats(cats);
基于lodash的实现
如果项目已全局引入lodash,可以通过groupBy先按cat_id分组,再对每个分组取order最小的条目:
const uniqueCats = _(cats) .groupBy('cat_id') .map(group => _.minBy(group, (item) => Number(item.order))) .value();
内容的提问来源于stack exchange,提问作者kaster
相关产品推荐
相关产品推荐

