编写JavaScript通用数组去重工具遇问题:调用后仍存重复项求解答
问题分析与解决思路
先帮你拆解下当前代码里的核心问题,咱们一步步来修正:
1. 你的工具函数deDuplicate的致命问题
咱们先看你写的工具函数:
publicMethods.deDuplicate = function(array, key, type) { var providedArray = []; // 这里创建了一个空数组,完全没用到传入的array参数! var uniqueArray = providedArray.filter(function(value, index, self) { return self.indexOf(value) === index; return providedArray; // 这行永远不会执行,因为前面已经return了 }); };
这里有几个明显的错误:
- 你完全忽略了传入的
array参数,反而在处理一个空数组providedArray,等于这个函数根本没碰你要去重的productArr filter回调里的第二个return无效,而且整个函数没有返回任何结果,也没有修改原数组,所以调用后productArr当然还是原样- 你定义了
key和type参数,但完全没用到,说明你可能想支持对象数组按指定key去重,但当前逻辑没实现
2. 调用时机的问题
你现在是在循环里每push一个元素就调用一次去重,这不仅没必要(浪费性能),而且就算工具函数正确了,每次去重后又push新元素,最后还是要再去重一次,正确的做法是先把所有元素push完,再调用一次去重函数。
3. 修正后的工具函数
咱们分两种情况写:一种是处理普通数组(比如你的productArr是字符串数组),另一种是支持对象数组按指定key去重(对应你工具函数里的key参数):
情况1:处理普通数组(如字符串/数字数组)
publicMethods.deDuplicate = function(array) { // 方法1:用filter去重,和你原逻辑一致,但要正确处理传入的数组 return array.filter(function(value, index, self) { return self.indexOf(value) === index; }); // 方法2:用ES6的Set更高效,推荐 // return [...new Set(array)]; };
情况2:支持对象数组按指定key去重(比如根据对象的name属性去重)
publicMethods.deDuplicate = function(array, key) { if (!key) { // 如果没传key,就按普通数组去重 return [...new Set(array)]; } // 用Map记录已出现的key值,实现去重 const map = new Map(); return array.filter(item => { if (!map.has(item[key])) { map.set(item[key], true); return true; } return false; }); };
4. 正确的调用方式
var productArr = []; // 先把所有元素push到数组里 for (var p in theData) { var theProduct = theData[p]; productArr.push(theProduct.name); } // 最后调用一次去重函数,覆盖原数组或者接收新数组 productArr = publicMethods.deDuplicate(productArr);
另外补充下:你原来的“无工具版本”其实逻辑也有问题——你在循环里每次都filterproductArr得到theProductSelect,但根本没把这个去重后的数组赋值回productArr,所以原版本其实也会存在重复项,可能你是写错了?正确的无工具版本应该是每次push前判断是否存在,或者最后统一去重:
var productArr = []; for (var p in theData) { var theProduct = theData[p]; // 先判断是否已存在,不存在再push if (productArr.indexOf(theProduct.name) === -1) { productArr.push(theProduct.name); } }
内容的提问来源于stack exchange,提问作者erics15
相关产品推荐
相关产品推荐

