JavaScript数组筛选:按指定价格差值规则生成目标数组
按指定价格阈值筛选JavaScript对象数组的实现
需求说明
给定一个包含price属性的JavaScript对象数组lists,以及一个可自定义的正整数阈值(示例值为1),需按照以下规则筛选生成新数组finalList:
- 必须保留数组的第一个元素
- 遍历后续元素时:
- 若当前元素价格大于上一个遍历的元素价格,计算它与第一个元素价格的差值,差值≥阈值则保留该元素
- 若当前元素价格小于等于上一个遍历的元素价格,计算它与上一个被保留元素价格的差值,差值≥阈值则保留,相等则直接忽略
- 保留元素时要同步更新「上一个被保留元素」的记录;无论当前元素是否被保留,都要更新「上一个遍历元素」的记录
示例输入
let lists = [ { id: "1", price: 10 }, { id: "2", price: 10.5 }, { id: "3", price: 11 }, { id: "4", price: 11.3 }, { id: "5", price: 12 }, { id: "6", price: 11.5 }, { id: "7", price: 12 }, { id: "8", price: 11 }, ] const threshold = 1;
目标输出
let finalList = [ { id: "1", price: 10 }, { id: "3", price: 11 }, { id: "4", price: 11.3 }, { id: "5", price: 12 }, { id: "8", price: 11 }, ]
实现代码
function filterByPriceThreshold(lists, threshold) { if (!lists || lists.length === 0) return []; // 初始化状态:第一个元素直接保留,同时记录关键状态 const initialState = { finalList: [lists[0]], lastTraversedItem: lists[0], lastKeptItem: lists[0], firstItem: lists[0] }; // 从第二个元素开始遍历处理 return lists.slice(1).reduce((state, currentItem) => { const { finalList, lastTraversedItem, lastKeptItem, firstItem } = state; if (currentItem.price > lastTraversedItem.price) { // 价格上涨:和第一个元素比差值 const diff = currentItem.price - firstItem.price; if (diff >= threshold) { finalList.push(currentItem); state.lastKeptItem = currentItem; } } else { // 价格持平/下跌:和上一个保留元素比差值(取绝对值确保非负) const diff = Math.abs(currentItem.price - lastKeptItem.price); if (diff >= threshold && currentItem.price !== lastKeptItem.price) { finalList.push(currentItem); state.lastKeptItem = currentItem; } } // 无论是否保留,都更新上一个遍历元素的记录 state.lastTraversedItem = currentItem; return finalList; }, initialState); } // 调用示例 const threshold = 1; const finalList = filterByPriceThreshold(lists, threshold); console.log(finalList);
代码逻辑解释
- 边界处理:先判断输入数组是否为空,避免空指针报错
- 状态初始化:用
initialState维护四个关键跟踪状态,确保遍历过程中基准数据准确 - 分支处理:根据当前元素与上一个遍历元素的价格关系,分别执行不同的差值判断逻辑,符合条件则将元素加入结果数组并更新保留元素记录
- 状态同步:每次遍历后强制更新「上一个遍历元素」的记录,保证下一次遍历的基准正确
内容的提问来源于stack exchange,提问作者Ben Davidsson
相关产品推荐
相关产品推荐

