如何遍历JS对象数组并筛选日期唯一的对象存入新数组?
解决JavaScript对象数组按日期去重的问题
嘿,我懂你碰到的麻烦了——在map里用push确实容易把逻辑搞乱,毕竟map本来是用来转换数组元素的,不是做这种“累加筛选”的活儿,咱们换个思路来搞定这个需求。
你的目标很明确:从weatherArray里提取每个对象dt_txt的日期部分,然后把每个日期只保留一个对应的对象存入新数组。下面给你几个靠谱的方案:
方案一:用filter + Set(最直观高效)
这种方式利用filter筛选符合条件的元素,同时用Set来快速记录已经出现过的日期,避免重复:
const weatherArray = [ { dt: 1526871600, dt_txt: "2018-05-21 03:22:00" }, { dt: 1526871600, dt_txt: "2018-05-22 03:30:00" }, { dt: 1526871600, dt_txt: "2018-05-21 03:50:00" }, { dt: 1526871600, dt_txt: "2018-05-23 03:17:00" }, { dt: 1526871600, dt_txt: "2018-05-23 03:23:00" } ]; const seenDates = new Set(); const uniqueDateWeather = weatherArray.filter(item => { // 提取dt_txt里的日期部分(分割空格取前半段) const datePart = item.dt_txt.split(' ')[0]; // 如果这个日期没出现过,就加入Set并保留当前对象 if (!seenDates.has(datePart)) { seenDates.add(datePart); return true; } // 否则过滤掉 return false; }); console.log(uniqueDateWeather);
方案二:用reduce(适合复杂累加场景)
reduce可以直接把结果和已记录的日期都放在累加器里,一步到位:
const uniqueDateWeather = weatherArray.reduce((acc, current) => { const datePart = current.dt_txt.split(' ')[0]; // 检查当前日期是否已经在结果数组里存在 if (!acc.seenDates.has(datePart)) { acc.seenDates.add(datePart); acc.result.push(current); } return acc; }, { result: [], seenDates: new Set() }).result;
为什么你之前的map方法会出问题?
map的核心作用是把数组里的每个元素转换成新元素,返回一个等长的新数组,它不应该用来做修改外部变量(比如push到另一个数组)这种“副作用”操作。虽然硬写也能得到结果,但代码可读性差,而且很容易因为逻辑混乱出bug——你说的“递归问题”其实大概率是误用map导致的逻辑混乱,不是真的递归哦。
这两种方案都能高效完成去重,而且代码清晰易维护,选哪个看你自己的习惯就行~
内容的提问来源于stack exchange,提问作者adamscott
相关产品推荐
相关产品推荐

