如何高效过滤购物清单:移除重复项并保留计数更高的条目?
优化购物清单去重并保留高count条目的方案
首先得给你点个赞——能靠试错把功能跑通已经很厉害了!不过你的现有代码确实还有不少可以优化的地方,比如:
- 误用了
map方法:map的核心是返回一个新数组,但你这里并没有利用它的返回值,反而在内部做了很多副作用操作,代码可读性和效率都打了折扣 removeDups变量会被重复赋值,最后可能只保留了最后一组重复项的处理结果(比如原数组里Bananas的处理结果会被后面Beans的逻辑覆盖),这显然不是你想要的最终效果
接下来给你分享两种更简洁高效的解法,都是业界常用的处理方式:
方法一:使用Array.reduce(最推荐)
reduce天生适合这种需要累积处理、分组比较的场景。我们可以把商品按item名称作为键存入一个临时对象,每次遇到相同的商品就对比count值,保留数值更大的那一个,最后把对象里的取值转成数组就行:
const groceryList = [ { item: "Bananas", count: 4 }, { item: "Bananas", count: 3 }, { item: "Brussel Sprouts", count: 2 }, { item: "Bacon", count: 100 }, { item: "Beans", count: 19 }, { item: "Beans", count: 5 } ]; const filteredList = Object.values(groceryList.reduce((acc, current) => { // 如果当前商品不在累积对象里,或者当前count更大,就更新条目 if (!acc[current.item] || current.count > acc[current.item].count) { acc[current.item] = current; } return acc; }, {})); console.log(filteredList); // 输出结果: // [ // { item: 'Bananas', count: 4 }, // { item: 'Brussel Sprouts', count: 2 }, // { item: 'Bacon', count: 100 }, // { item: 'Beans', count: 19 } // ]
为什么这个方法更优?
- 只需要遍历数组一次,时间复杂度为O(n),比你的原方法(多次执行
filter遍历)效率高很多 - 代码逻辑清晰,没有多余的副作用变量,读起来一目了然
- 用
Object.values直接把分组后的对象转成目标数组,简洁又直观
方法二:使用Set结合基础数组方法(适合理解基础集合操作)
如果你更习惯用基础数组方法,也可以先提取所有不重复的商品名称,再对每个名称筛选出count最大的条目:
const groceryList = [ { item: "Bananas", count: 4 }, { item: "Bananas", count: 3 }, { item: "Brussel Sprouts", count: 2 }, { item: "Bacon", count: 100 }, { item: "Beans", count: 19 }, { item: "Beans", count: 5 } ]; // 获取所有不重复的商品名称集合 const uniqueItems = [...new Set(groceryList.map(item => item.item))]; // 对每个商品筛选出count值最大的条目 const filteredList = uniqueItems.map(itemName => { return groceryList .filter(item => item.item === itemName) .reduce((maxItem, currentItem) => { return currentItem.count > maxItem.count ? currentItem : maxItem; }); }); console.log(filteredList); // 输出结果和上面一致
这个方法的可读性也不错,但需要遍历数组多次(先map取名称,再对每个名称做filter+reduce),时间复杂度为O(n²),数据量大的时候效率不如第一种方法。
最后再提一句你的原代码:其实调整变量逻辑可以避免覆盖问题,但整体还是不如上面的解法高效简洁~
内容的提问来源于stack exchange,提问作者adamscott
相关产品推荐
相关产品推荐

