JavaScript如何从对象数组中提取唯一id对应的最早日期对象?
解决方案
你的核心实现逻辑是可行的:先将数组按日期升序排列,再利用Map键唯一的特性,同个id只会保留第一个出现的(也就是日期最早的)对象。现有代码只需要修正两个小问题即可正常运行:
- 第二行过滤逻辑直接引用了原数组
array,没有使用第一行过滤完非空id的withId,会导致第一行的id非空过滤失效 - 注意属性名大小写要和实际数据对齐:示例数组的id字段为小写
id、日期字段为date,你的代码中使用的是大写Id、UtcStart,实际运行时要和业务字段匹配
适配示例场景的可运行代码
const array = [ {id: 1, date: '01-12-2021'}, {id: 2, date: '02-08-2021'}, {id: 2, date: '03-02-2021'}, {id: 3, date: '02-08-2021'} ] // 过滤id为空的无效项 const withId = array.filter(g => g.id != null); // 按日期升序排序,更早的日期排在数组前面 withId.sort((a, b) => moment(a.date, 'MM-DD-YYYY') - moment(b.date, 'MM-DD-YYYY')); // 利用Map去重,同id仅保留第一个(即日期最早的)对象 const unique = [...new Map(withId.map(x => [x.id, x])).values()];
运行后unique的输出和你预期的结果完全一致。
更高性能的实现方案
如果不想修改原数组的排序,也可以通过单次遍历直接存储每个id的最早日期对象,省去排序步骤,数据量越大性能优势越明显:
const resultMap = new Map() array.forEach(item => { // 跳过id为空的项 if (!item.id) return const currentDate = moment(item.date, 'MM-DD-YYYY') // 没有存过同id的项,或者当前项日期比已存的更早,就更新存储内容 if (!resultMap.has(item.id) || currentDate < moment(resultMap.get(item.id).date, 'MM-DD-YYYY')) { resultMap.set(item.id, item) } }) const unique = [...resultMap.values()]
内容的提问来源于stack exchange,提问作者Derin Kadir
相关产品推荐
相关产品推荐

