javascript去重并保留最后一次出现的元素有三种主要方法:一是反向遍历+set再反转,语义清晰高效;二是用map自动覆盖同key值,适合按属性去重;三是reverse+reduce+includes,简洁但性能较差;还可直接用filter+lastindexof,简洁但时间复杂度为o(n²)。

JavaScript 中去重并保留最后一次出现的元素,核心思路是反向遍历 + 记录已出现项,或者用 Map / Object 自动覆盖同 key 的特性来“天然保留最后值”。下面几种实用方法供你按场景选择:
方法一:反向遍历 + Set(推荐,语义清晰)
从数组末尾往前遍历,用 Set 记录已见过的值,只保留第一次遇到(即原数组中最后一次出现)的元素,再反转结果。
function uniqueKeepLast(arr) {
const seen = new Set();
const result = [];
for (let i = arr.length - 1; i >= 0; i--) {
if (!seen.has(arr[i])) {
seen.add(arr[i]);
result.push(arr[i]);
}
}
return result.reverse();
}
<p>// 示例
console.log(uniqueKeepLast([1, 2, 3, 2, 4, 1])); // [3, 2, 4, 1]
</p>
方法二:用 Map 实现“自动覆盖”(适合对象或复杂值)
利用 Map 键唯一、后设覆盖前设的特性,遍历一次存入 Map,再提取 values() —— 这样自然保留每个键最后对应的值。若需按原顺序返回,可配合 Array.from(map.values())。
- 适用于原始值(如字符串、数字),也支持对象作为键(用
Map) - 若数组元素是对象,想按某个字段(如
id)去重,可先映射为[id, item]数组再转 Map
function uniqueByPropKeepLast(arr, keyFn = x => x) {
const map = new Map();
for (const item of arr) {
const key = keyFn(item);
map.set(key, item); // 后出现的会覆盖先出现的
}
return Array.from(map.values());
}
<p>// 示例:按 id 去重,保留最后出现的对象
const list = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 1, name: 'a2'}];
console.log(uniqueByPropKeepLast(list, x => x.id));
// [{id: 1, name: 'a2'}, {id: 2, name: 'b'}]
</p>
方法三:reduce 反向累积(函数式写法)
将数组反转后用 reduce,维护一个不含重复项的累加数组,遇到新值才加入——等效于方法一,但更紧凑。
function uniqueKeepLast(arr) {
return arr
.reverse()
.reduce((acc, item) => acc.includes(item) ? acc : [...acc, item], [])
.reverse();
}
注意:此写法在大数组中性能较差(includes 是 O(n)),仅适合小数据量或追求简洁时使用。补充:为什么不能直接用 filter + indexOf?
indexOf 总是返回首次出现索引,所以 arr.filter((x, i) => arr.indexOf(x) === i) 保留的是第一次;而 lastIndexOf 虽能找末次位置,但无法在 filter 中直接对应到“当前是否为最后一次”——因为 i 是当前下标,lastIndexOf(x) 是它在全数组中最右位置,二者相等才说明此处是最后一次。所以其实可以这样写(但效率略低):
arr.filter((item, i) => arr.lastIndexOf(item) === i)
✅ 正确,✅ 简洁,⚠️ 对长数组多次调用 lastIndexOf(O(n²) 时间复杂度),慎用于大数据。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











