Javascript 如何在频繁更新的滑动阵列中有效跟踪滚动最小/最大值

Javascript 如何在频繁更新的滑动阵列中有效跟踪滚动最小/最大值,javascript,algorithm,Javascript,Algorithm,考虑以下javascript数据结构: let sensors = { sensor1: { min: 1.00, max: 9.00, data: [ { timestamp: 1517760374400, value: 1.00 }, { timestamp: 1517760374500, value: 2.00 }, {

考虑以下javascript数据结构:

let sensors = { 
  sensor1: {
    min: 1.00,
    max: 9.00,
    data: [
      {
        timestamp: 1517760374400,
        value: 1.00
      },
      {
        timestamp: 1517760374500,
        value: 2.00
      },
      {
        timestamp: 1517760374600,
        value: 9.00
      },
      {
        timestamp: 1517760374700,
        value: 1.00
      },
      {
        timestamp: 1517760374800,
        value: 3.00
      },
      {
        timestamp: 1517760374900,
        value: 1.00
      },
      {
        timestamp: 1517760375000,
        value: 9.00
      },
      {
        timestamp: 1517760375100,
        value: 8.00
      },
    ]
  },
  // sensor2, sensor3, etc...
}
想象一下,每个传感器可能有数千个时间戳数据

最初,您可以通过检查对象是否大于或小于当前最大值来轻松设置最小值/最大值,每次添加对象时都可以这样做

但棘手的部分和我的问题是:

数组的大小是有限的-在本例中,我们将其设置为8的长度

每当在项目8之后添加新项目时,达到限制时,第一个项目将被删除,第n个项目将被推入数组的末尾

问题是可能会有更多具有相同值的项,即使没有,我们也无法知道下一个是哪个min/max,而不需要再次迭代整个数组

这应该可以扩展到数千个数组项,并且在理想情况下(尽可能低的cpu利用率)大约每秒运行一次。我真的认为每秒循环数千个项不够有效

您是否看到了其他跟踪数组的最小/最大值的方法,这些值每秒钟都在变化?

数据结构:

let sensors = { 
  sensor1: {
    min: 1.00,
    max: 9.00,
    data: [
      {
        timestamp: 1517760374400,
        value: 1.00
      },
      {
        timestamp: 1517760374500,
        value: 2.00
      },
      {
        timestamp: 1517760374600,
        value: 9.00
      },
      {
        timestamp: 1517760374700,
        value: 1.00
      },
      {
        timestamp: 1517760374800,
        value: 3.00
      },
      {
        timestamp: 1517760374900,
        value: 1.00
      },
      {
        timestamp: 1517760375000,
        value: 9.00
      },
      {
        timestamp: 1517760375100,
        value: 8.00
      },
    ]
  },
  // sensor2, sensor3, etc...
}
队列大小为N以存储N个项目

用于跟踪最小/最大项的最小/最大堆

跟踪每个项目频率的哈希映射

当有即将到来的数据时,更新新项的频率,如果堆中没有,则添加它

当您需要弹出一个项目时,降低频率,当head的频率=0时,从堆中移除

解决方案是在堆的顶部

伪代码:

常量交换=数据,i,j=>{ 设温度=数据[i]; 数据[i]=数据[j]; 数据[j]=温度; } 类堆{ 建造师{ 这个.data=[]; this.inHeap={}; 此值为0.size=0; } 头{ 返回此.数据[0]; } //添加项目OlogN; 地址号{ 如果!这个.inHeap[数字]{ this.data[this.size++]=数字; 让电流=此值。尺寸-1; 当当前>0时{ 如果this.data[current>>1]>1,当前; 当前>>=1; }否则{ 打破 } } this.inHeap[number]=true; } } //取下头部; 除去{ 这个尺寸-; 删除此.inHeap[this.data[0]]; this.data[0]=this.data[this.size]; 设电流=0; 而电流*2+1<此尺寸{ 设next=当前*2+1; 如果当前*2+2this.data[current*2+1]{ next=当前*2+2; } 如果this.data[当前]听起来很有趣。我认为你会遇到一个问题,你只是不知道一个值在未来是否会是一个极端的最大/最小值

我的想法是为当前的最大值和最小值添加一个过期计数器。每次不替换滚动最小值/最大值时,此计数器将递减。当使用新的新值更新时,它将重置为8。Min和max显然有单独的计数器

现在,如果计数器减为0,并且最小/最大值变为陈旧值,则只需循环遍历值,它不再在列表中。例如,如果您的最小值计数器过期,您现在必须确定当前在8个列表中剩余的最小值。在本例中,您将重置过期计数器以匹配迭代次数,直到新的最小值从列表8(它的索引)中删除


这可能会为您节省一些CPU周期

嗨,丹尼尔,我想你是对的,但是你有没有可能给我更多的帮助?我不太能够把这些点连接起来,看看它是如何应用到我的数据集的。队列=数据数组?最小/最大堆你这是什么意思-可以有多个项目,不同的时间戳,具有相同的最小/最大值。我真的很想了解你的解决方案,因为我觉得这是一条路要走。有没有可能编写一些快速的伪代码来描述您所建议的结构是什么样子的?我认为只有在堆保持排序时,堆头才是解决方案,对吗?还是我错过了什么我不知道。不过,我很想看到这个解决方案付诸实施。但是这些项是排序的,因为它们每秒都被推到数组的末尾,所以时间戳应该是有序的。我的堆实现中有一个bug,我忘了添加其他{break;}不需要,您可以使用比较函数作为参数自定义堆。也许您需要这样的东西:只有当删除的项包含最小值或最大值时,才必须重新计算最小值或最大值,并且只有当它需要时,这意味着它可以保持为未定义,直到需要该值