如何在数组对象中查找近邻范围对象并获取对应数组索引
解决方案
好的,我来帮你搞定这个问题!你已经用reduce找到了最接近指定时间的对象,现在只需要调整代码逻辑,就能获取它们的索引并提取出目标范围的对象。
1. 获取最接近时间点的元素索引
你之前的reduce只返回了最接近的对象,但没跟踪对应的索引。我们可以修改reduce的逻辑,让它在比较差值的同时记录元素的索引:
// 获取最接近startTime的元素索引 const startIndex = DataSet.reduce((prevIndex, curr, currIndex) => { const currDiff = Math.abs(curr.time - startTime); const prevDiff = Math.abs(DataSet[prevIndex].time - startTime); // 差值更小就更新索引,若差值相等则保留先出现的元素(可按需调整) return currDiff < prevDiff ? currIndex : prevIndex; }, 0); // 初始值设为第一个元素的索引 // 获取最接近endTime的元素索引 const endIndex = DataSet.reduce((prevIndex, curr, currIndex) => { const currDiff = Math.abs(curr.time - endTime); const prevDiff = Math.abs(DataSet[prevIndex].time - endTime); return currDiff < prevDiff ? currIndex : prevIndex; }, 0);
在你的示例数据中,这段代码会得到:
startIndex = 1(对应time:1559923200的对象,和startTime差值仅为1)endIndex = 3(对应time:1560058490的对象,和endTime差值最小)
2. 提取近邻范围对象
拿到两个索引后,先确保起始索引小于等于结束索引(避免索引顺序颠倒的情况),再用数组的slice方法提取目标范围:
// 统一切片的起始和结束顺序 const sliceStart = Math.min(startIndex, endIndex); const sliceEnd = Math.max(startIndex, endIndex); // 提取两个索引之间的元素(左闭右开,不包含endIndex对应的元素,正好匹配你的示例) const ResultSet = DataSet.slice(sliceStart, sliceEnd);
运行这段代码后,ResultSet会完全符合你的期望:
[ {"time":1559923200,"value":10}, {"time":1559923000,"value":5} ]
完整整合代码
把所有逻辑放在一起的完整代码:
var startTime = 1559923201; var endTime = 1560009601; var DataSet = [ {"time":1549923201,"value":12}, {"time":1559923200,"value":10}, {"time":1559923000,"value":5}, {"time":1560058490,"value":4}, {"time":1560058800,"value":3}, {"time":1560059500,"value":2} ]; // 获取最接近startTime的索引 const startIndex = DataSet.reduce((prevIndex, curr, currIndex) => { const currDiff = Math.abs(curr.time - startTime); const prevDiff = Math.abs(DataSet[prevIndex].time - startTime); return currDiff < prevDiff ? currIndex : prevIndex; }, 0); // 获取最接近endTime的索引 const endIndex = DataSet.reduce((prevIndex, curr, currIndex) => { const currDiff = Math.abs(curr.time - endTime); const prevDiff = Math.abs(DataSet[prevIndex].time - endTime); return currDiff < prevDiff ? currIndex : prevIndex; }, 0); // 提取范围对象 const sliceStart = Math.min(startIndex, endIndex); const sliceEnd = Math.max(startIndex, endIndex); const ResultSet = DataSet.slice(sliceStart, sliceEnd); console.log("startIndex:", startIndex); console.log("endIndex:", endIndex); console.log("ResultSet:", ResultSet);
补充说明
- 如果需要包含最接近endTime的对象,只需把
sliceEnd改成sliceEnd + 1即可。 - 如果存在多个元素和目标时间的差值相同,当前逻辑会保留先出现的元素,你可以把判断条件改成
<=来保留后出现的元素。
内容的提问来源于stack exchange,提问作者Keyme
相关产品推荐
相关产品推荐

