如何在JavaScript中仅一次变量声明实现数组降序排序与contact_id去重?
合并数组排序与去重为单次变量声明的优化方案
首先,我们可以通过链式调用将排序和去重操作合并,只进行一次变量声明,同时还能优化去重的效率(原filter方法中每次调用map会额外遍历数组,性能较差)。
优化后的高效版代码
// 原始活动数组 const activityArr = [ { id: 1, contact_id: 2, some_field: true }, { id: 2, contact_id: 3, some_field: true }, { id: 3, contact_id: 4, some_field: false }, { id: 4, contact_id: 3, some_field: true }, { id: 5, contact_id: 4, some_field: false } ]; // 单次声明完成排序+去重 const sortedUniqueActivities = activityArr // 按id从高到低排序(修正原回调的不规范写法,返回数值而非布尔值) .sort((a, b) => b.id - a.id) // 使用reduce去重,仅保留每个contact_id的第一个出现项(即id最高的项) .reduce((uniqueArr, currentItem) => { // 检查当前contact_id是否已存在于结果数组中 const hasDuplicate = uniqueArr.some(item => item.contact_id === currentItem.contact_id); if (!hasDuplicate) { uniqueArr.push(currentItem); } return uniqueArr; }, []); console.log(sortedUniqueActivities); // 输出:[ { id: 5, contact_id: 4, some_field: false }, { id: 4, contact_id: 3, some_field: true }, { id: 1, contact_id: 2, some_field: true } ]
思路说明
- 链式调用简化流程:把
sort和reduce方法串联起来,直接将最终结果赋值给新变量,避免对原数组的多次重新赋值,一次声明就完成所有需求。 - 修正排序逻辑:原代码的
sort回调返回布尔值,不符合ECMAScript规范(正确的回调应返回负数/0/正数),改用b.id - a.id能确保跨浏览器的排序一致性。 - 提升去重效率:用
reduce替代原filter+map+indexOf的组合,只遍历数组一次,同时用some检查重复项,相比原方法减少了不必要的数组遍历,性能更优。
简化版(保留原filter逻辑的链式调用)
如果你想保留原filter的逻辑,也可以直接链式调用实现单次声明:
const sortedUniqueActivities = activityArr .sort((a, b) => b.id - a.id) .filter((obj, pos, self) => { return self.findIndex(item => item.contact_id === obj.contact_id) === pos; });
不过这个方法的效率低于reduce版本,因为findIndex会在每个filter迭代时遍历数组。
内容的提问来源于stack exchange,提问作者wobsoriano
相关产品推荐
相关产品推荐

