如何使用JavaScript在不修改原数组的情况下提取仅出现一次的元素?
提取数组中仅出现一次的元素(不修改原数组)
需求回顾
给定数组:
var arr = [1, 1, 1, 5, 3, 4, 6, 6];
你给出的函数框架为 function uniqueRetriever(bla, boi) { ... }(这里的bla和boi应该是占位参数),我们需要实现该函数,调用后返回仅出现一次的元素组成的数组 [5, 3, 4],且绝对不能修改原数组。
实现思路
核心是先统计每个元素在数组中的出现次数,再筛选出次数为1的元素。因为不能修改原数组,所以所有操作都要基于原数组的读取,不改变原数组的任何内容。
方案一:用reduce统计次数 + filter筛选(高效推荐)
这是最直观且性能优异的方案,先通过reduce生成一个记录元素出现次数的映射对象,再遍历原数组筛选出符合条件的元素:
var arr = [1, 1, 1, 5, 3, 4, 6, 6]; function uniqueRetriever(inputArr) { // 第一步:统计每个元素的出现次数,生成次数映射表 const countMap = inputArr.reduce((acc, current) => { acc[current] = (acc[current] || 0) + 1; return acc; }, {}); // 第二步:筛选出仅出现一次的元素,返回新数组(原数组不受影响) return inputArr.filter(item => countMap[item] === 1); } var unique = uniqueRetriever(arr); console.log(unique); // 输出: [5, 3, 4] // 验证原数组未被修改 console.log(arr); // 输出: [1, 1, 1, 5, 3, 4, 6, 6]
代码解释
reduce遍历原数组,用对象countMap记录每个元素的出现次数:键是数组元素,值是对应出现的次数。filter遍历原数组,只保留countMap中次数为1的元素,返回全新的数组,完全不会修改原数组的内容。
方案二:用indexOf和lastIndexOf直接判断(简洁版)
如果不想额外创建统计对象,可以利用数组的内置方法:一个元素如果仅出现一次,那么它的首次出现索引和最后出现索引是完全相同的。
var arr = [1, 1, 1, 5, 3, 4, 6, 6]; function uniqueRetriever(inputArr) { return inputArr.filter(item => inputArr.indexOf(item) === inputArr.lastIndexOf(item)); } var unique = uniqueRetriever(arr); console.log(unique); // 输出: [5, 3, 4] console.log(arr); // 原数组未被修改
注意点
这个方案代码更简洁,但时间复杂度比方案一高(indexOf和lastIndexOf每次都会遍历数组),如果处理的是大型数组,更推荐使用方案一。
内容的提问来源于stack exchange,提问作者Dilawar Mahmood
相关产品推荐
相关产品推荐

