You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript获取指定范围内对象数据:修复错误及ES6实现

如何从对象数组中筛选timestamp在指定范围内的数据?

嘿,我看你在写时间范围筛选函数的时候遇到了几个问题,咱们来一步步拆解问题,然后给出可行的解决方案:


你的当前函数存在的核心问题

咱们先看看你写的getValuesInRange函数为什么会报错,以及逻辑上的漏洞:

  1. indexOf is not defined 错误:indexOf是数组的原型方法,你直接全局调用indexOf(from)肯定会报错——你既没有指定要在哪个数组里查找,甚至连要处理的原始data数组都没传入函数里。
  2. 空数组sortedArray:你初始化了sortedArray但完全没有把原始数据赋值给它,后续的循环根本没有任何数据可以处理,等于白跑。
  3. 字段不匹配:你的数据对象里用的是timestamp字段,但代码里却写了valueAtIndex.key和valueAtIndex.value,这完全对应不上;而且从你的需求来看,你应该是要保留整个对象或者里面的字段,而不是什么key/value结构。
  4. 逻辑缺失:函数既没有对原始数据做排序(虽然你的示例数据是有序的,但通用场景下必须考虑无序的情况),也没有正确关联输入的from/to和数据的timestamp字段。

正确的实现思路

幸运的是,你的timestamp是ISO 8601格式的字符串,这种字符串可以直接按字典序比较(因为它的时间单位是从年到秒依次排列的),所以不需要转成Date对象也能直接比较大小;当然,转成Date对象的时间戳来比较也是完全可行的,两种方式都没问题。

修复后的基础版函数

首先,我们把data数组传入函数,修正字段和逻辑:

function getValuesInRange(data, from, to) {
  // 先复制数组并按timestamp排序(处理原始数据无序的情况)
  const sortedArray = [...data].sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
  
  const filteredValues = [];
  // 找到第一个timestamp >= from的元素索引
  let index = sortedArray.findIndex(item => item.timestamp >= from);
  
  // 如果没有符合条件的元素,直接返回空数组
  if (index === -1) return filteredValues;
  
  while (index < sortedArray.length) {
    const currentItem = sortedArray[index];
    // 检查是否在[from, to)的左闭右开区间内
    if (currentItem.timestamp < to) {
      filteredValues.push(currentItem); // 若只需提取某个字段,比如temperature,改为currentItem.temperature即可
      index++;
    } else {
      break;
    }
  }
  
  return filteredValues;
}

// 测试用例
const data = [
  { timestamp: '2015-09-01T16:00:00.000Z', temperature: 27.1, dewPoint: 17.1 },
  { timestamp: '2015-09-01T16:10:00.000Z', temperature: 27.2, dewPoint: 17.2 },
  { timestamp: '2015-09-01T16:20:00.000Z', temperature: 27.3, dewPoint: 17.3 },
  { timestamp: '2015-09-01T16:30:00.000Z', temperature: 27.4, dewPoint: 17.4 }
];
const fromDateTime = data[0].timestamp;
const toDateTime = data[2].timestamp;
console.log(getValuesInRange(data, fromDateTime, toDateTime));
// 输出:[{timestamp: '2015-09-01T16:00:00.000Z', ...}, {timestamp: '2015-09-01T16:10:00.000Z', ...}]

ES6 简洁等价实现

利用数组的filter方法,结合ISO字符串的直接比较,代码会非常简洁:

const getValuesInRangeES6 = (data, from, to) => 
  // 若原始数据已按timestamp升序排列,可去掉sort步骤优化性能
  [...data]
    .sort((a, b) => a.timestamp.localeCompare(b.timestamp)) // 用localeCompare也能正确比较ISO字符串
    .filter(item => item.timestamp >= from && item.timestamp < to);

// 测试调用
console.log(getValuesInRangeES6(data, fromDateTime, toDateTime));
// 输出结果和上面一致

如果你的原始数据确定已经是按timestamp升序排列的,那么可以直接去掉sort步骤,进一步提升性能:

const getValuesInRangeES6Optimized = (data, from, to) => 
  data.filter(item => item.timestamp >= from && item.timestamp < to);

额外说明

  • 如果你需要的是闭区间(包含to对应的时间),只需要把条件改成item.timestamp <= to即可。
  • 如果你的timestamp不是ISO格式,那必须转成Date对象的时间戳来比较,比如new Date(item.timestamp).getTime()。

内容的提问来源于stack exchange,提问作者Null isTrue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:29:40