如何使用高阶函数的filter方法实现移除数组最贵商品且保留原序的JS函数
完全可以用高阶函数实现,并且可以直接通过你关心的
filter方法完成移除逻辑 你现有的基础循环实现本身就是拆成了两个独立的核心步骤,完全可以用语义更明确的高阶函数替换手写循环,代码量能缩减近一半,而且能100%对齐你现有代码的输出行为,不会出现逻辑偏差。
实现思路
整体逻辑和你原来的代码完全对齐,只是把手写的遍历过程换成对应语义的高阶方法:
- 第一步:遍历定位到价格最高的对象引用(注意这里是对象本身的引用,不是单独提取价格数值,这样才能和原代码一样精准定位要移除的单个元素,不会误删和最高项同价的其他商品)
- 第二步:通过
filter方法把非目标元素的项全部保留,自动生成新数组,全程不修改原数组,也完全保留元素原有顺序
具体实现代码:
function removeMostExpensive(list) { // 用reduce替代原代码里查找最高价元素的基础循环 const mostExpensive = list.reduce((maxItem, currentItem) => currentItem.price > maxItem.price ? currentItem : maxItem , list[0]); // 用filter替代原代码手动push的过滤循环 return list.filter(item => item !== mostExpensive); }
和原实现的一致性校验
上面的写法和你原来的基础循环代码没有任何行为差异:
- 初始逻辑一致:把数组第一个元素作为最高价的初始比较值
- 更新规则一致:只有遇到价格严格更高的元素,才会更新最高价的对象引用;遇到同价格的最高项不会替换引用——如果出现多个同价的最高值,最终会移除最后出现的那个最高价商品,和原代码行为完全匹配
- 过滤规则一致:只移除被定位到的目标对象,其他元素全部按原顺序保留
- 无副作用:不会修改传入的原数组参数,返回的新数组结构和原代码输出完全相同
容易踩坑的简化方向
很多人第一反应会直接提取最高价格数值做过滤判断,这种写法虽然代码更短,但和原逻辑有本质差异,使用时要注意区分:
如果你的需求后续变更为「移除所有价格等于最高值的商品」,可以用下面的简化写法,不需要定位对象引用,直接判断价格即可:
function removeAllMaxPriceItems(list) { // 提取全列表的最高价格数值 const maxPrice = Math.max(...list.map(item => item.price)); // 过滤掉所有价格等于最高值的元素 return list.filter(item => item.price !== maxPrice); }注意这个写法和你原代码的核心差异:如果数组里有多个商品同时达到最高价格,会把这些商品全部移除,和你原代码“仅移除1个最高项”的逻辑不匹配,使用前要确认自己的实际需求。
实际运行效果
用你贴的测试用例运行,输出结果和原代码完全一致:移除价格12.75的rice商品,剩余的chicken、celery、carrots、green beans按原顺序组成新数组返回。
内容的提问来源于stack exchange,提问作者Ron Skinner
相关产品推荐
相关产品推荐

