保留最后出现元素的数组去重需逆序处理或记录最后索引:方法一用reverse+set+reverse(简洁但改原数组);方法二用filter+lastindexof(语义清但性能低);方法三用map记最后索引再排序提取(高效通用);对象数组可reduce+对象键覆盖实现。

JavaScript 数组去重时默认多用 Set 或 filter + indexOf,但它们都保留**第一次出现**的元素。若想保留**最后出现**的重复项(即去重后每个值取它在原数组中最后一次出现的位置),关键在于**逆序处理 + 去重 + 恢复顺序**,或用对象/Map 记录最后索引。
方法一:reverse → Set → reverse(简洁推荐)
利用 reverse() 将数组倒序,用 Set 去重(此时保留的是倒序后的“首次”,即原数组的“末次”),再翻转回来:
const arr = [1, 2, 3, 2, 4, 1, 5]; const uniqueLast = [...new Set(arr.reverse())].reverse(); // → [3, 2, 4, 1, 5]
⚠️ 注意:该方法会修改原数组(因 reverse() 是原地操作)。如需不改原数组,先拷贝:
const uniqueLast = [...new Set([...arr].reverse())].reverse();- 适用于基础类型(number/string/boolean),不支持对象等引用类型
方法二:用 reduce + lastIndexOf(语义清晰)
遍历数组,对每个元素检查它是否是其最后一次出现——即 lastIndexOf(item) === 当前索引:
const arr = [1, 2, 3, 2, 4, 1, 5]; const uniqueLast = arr.filter((item, i) => arr.lastIndexOf(item) === i); // → [3, 2, 4, 1, 5]
✅ 不修改原数组,逻辑直观;
❌ 对于长数组性能略低(lastIndexOf 每次都从尾部扫描)。
方法三:用 Map 记录最后索引(兼顾性能与通用性)
一次遍历记录每个值最后一次出现的索引,再按索引升序提取对应元素(保证结果顺序与原数组中最后出现位置一致):
const arr = [1, 2, 3, 2, 4, 1, 5]; const lastIndexMap = new Map(); arr.forEach((item, i) => lastIndexMap.set(item, i)); const indices = [...lastIndexMap.values()].sort((a, b) => a - b); const uniqueLast = indices.map(i => arr[i]); // → [3, 2, 4, 1, 5]
✅ 时间复杂度 O(n),适合大数组;
✅ 可扩展支持对象(用 JSON.stringify 作 key,注意循环引用限制);
⚠️ 若需严格保持“最后出现顺序”,此法天然满足(因按索引排序)。
补充:对象数组按某字段去重(保留最后)
例如按 id 去重,保留相同 id 中最后出现的对象:
const users = [{id:1,name:'a'}, {id:2,name:'b'}, {id:1,name:'a2'}, {id:3,name:'c'}];
const uniqueByIdLast = Object.values(
users.reduce((acc, cur) => {
acc[cur.id] = cur; // 后来者覆盖前者
return acc;
}, {})
);
// → [{id:1,name:'a2'}, {id:2,name:'b'}, {id:3,name:'c'}]
本质是用对象(或 Map)做键值映射,赋值即自动覆盖,自然保留最后一次。
不复杂但容易忽略:保留“最后出现”不是简单反转,而是要抓住“每个值的最终落点”。选哪种方法取决于数据类型、性能要求和是否需要可读性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











