Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何构造特定于时间的数据,以便找到最近的点?_Javascript_Function_Data Structures - Fatal编程技术网

Javascript 如何构造特定于时间的数据,以便找到最近的点?

Javascript 如何构造特定于时间的数据,以便找到最近的点?,javascript,function,data-structures,Javascript,Function,Data Structures,这在一行问题中有点难以表达,但我正在寻找一些用Javascript构建数据和编写函数的建议/最佳实践 我有几个定期改变状态的项目。我的数据包含itemID、时间戳和状态。我目前正在将它构造为一个对象数组(针对每个项目),具有包含时间戳和状态的历史优先级。(见下文) 我正在寻找一个函数,它允许我使用最新的过去更新,轻松地获取给定时间内每个对象的状态。我不确定我的数据结构是否允许这样做,或者是否允许,如何编写函数。(在本例中,我将把时间戳缩短为4位数字) 我希望能够有这样一个功能: getStat

这在一行问题中有点难以表达,但我正在寻找一些用Javascript构建数据和编写函数的建议/最佳实践

我有几个定期改变状态的项目。我的数据包含itemID、时间戳和状态。我目前正在将它构造为一个对象数组(针对每个项目),具有包含时间戳和状态的历史优先级。(见下文)

我正在寻找一个函数,它允许我使用最新的过去更新,轻松地获取给定时间内每个对象的状态。我不确定我的数据结构是否允许这样做,或者是否允许,如何编写函数。(在本例中,我将把时间戳缩短为4位数字)

我希望能够有这样一个功能:

 getStatus(1260);
回来

 {1: 'in-use', 2: 'open', 3: 'reset'}
每个id,以及根据查询时间之前的最新历史记录传入时的状态

我完全不依附于这个数据结构。我还尝试将历史记录作为一个包含时间和状态的对象数组,但这意味着我每次都必须遍历整个数组。我最大的问题是,我的头脑在强迫我使用SQL方法来实现这一点,但我被困在客户端Javascript中

我的问题:什么是最好的数据结构?我将如何编写getStatus()函数

谢谢

我还尝试将历史记录作为一个包含时间和状态的对象数组,但这意味着我每次都必须遍历整个数组

如果对数组进行了排序,则不会这样做,因为这样可以直接访问最近的日期。您还可以使用二进制搜索来获取特定时间戳的状态。对于当前拥有的对象,始终必须枚举所有属性才能找到最佳匹配

var items = [
  { id: 1,
    history: [
      { timestamp: 1234, status: 'open'},
      { timestamp: 1256, status: 'in-use'},
      { timestamp: 1289, status: 'reset'},
      { timestamp: 1293, status: 'open'}
    ]
  },
  …
];
function index(arr, compare) { // binary search, with custom compare function
    var l = 0,
        r = arr.length - 1;
    while (l <= r) {
        var m = l + ((r - l) >> 1);
        var comp = compare(arr[m]);
        if (comp < 0) // arr[m] comes before the element
            l = m + 1;
        else if (comp > 0) // arr[m] comes after the element
            r = m - 1;
        else // this[m] equals the element
            return m;
    }
    return l-1; // return the index of the next left item
                // usually you would just return -1 in case nothing is found
}
// example:
function insertItem(history, timestamp, status) {
    var i = index(history, function(item) {
        return item.timestamp - timestamp;
    });
    history.splice(i+1, 0, {timestamp: timestamp, status: status});
}

function getStatus(time) {
    var result = {};
    function comparefn (item) {
        return item.timestamp - time;
    }
    for (var i=0; i<items.length; i++) {
        var pos = index(items[i].history, comparefn);
        result[items[i].id] = pos == -1
          ? undefined
          : items[i].history[pos].status;
    }
    return result;
}
var项目=[
{id:1,
历史:[
{时间戳:1234,状态:'打开'},
{时间戳:1256,状态:'正在使用'},
{时间戳:1289,状态:'reset'},
{时间戳:1293,状态:“打开”}
]
},
…
];
函数索引(arr,compare){//二进制搜索,带有自定义比较函数
var l=0,
r=arr.长度-1;
而(l>1);
var comp=比较(arr[m]);
if(comp<0)//arr[m]位于元素之前
l=m+1;
如果(comp>0)//arr[m]在元素后面,则为else
r=m-1;
else//此[m]等于元素
返回m;
}
返回l-1;//返回左下一项的索引
//通常,如果找不到任何内容,您只需返回-1
}
//例如:
函数插入项(历史记录、时间戳、状态){
var i=索引(历史记录、功能(项目){
return item.timestamp—时间戳;
});
拼接(i+1,0,{timestamp:timestamp,status:status});
}
函数getStatus(时间){
var result={};
功能比较n(项目){
return item.timestamp—时间;
}
对于(var i=0;i您可以使用循环:

// for each entry:
var n2 = n;
while (typeof items[n2] == "undefined" && n2 >= -1) {
    n2--;
}
if (n != -1) {returnedArray[idBeingProcessed] = items[n2];}
else {alert("Error handling here");}
// repeat for each item (id 1, id 2...)
如果找到答案,此操作将停止。它可能效率低下,但嘿,它可以工作:-)


也可以考虑使用一个数组,用于<代码>历史> /代码>对象。如果……………………我当然会切换到数组。现在我需要花一些时间来理解这个代码……好吧……我对索引函数有一些困惑——它看起来像是一个二进制排序,但是我不知道按位运算是怎么做的……var m=l+((r-l)>>1);这会被2除并取整吗?是的。它是数学地板((r-l)/2)的缩写

通过使用。它不是二进制排序,而是a:-)好的。我想我知道了。非常感谢!Bergi,我知道我迟到了两周,但我希望你能给我指出正确的方向。与原始帖子相同的情况,但现在我们需要添加对最近“正在使用”的搜索在给定时间之前。现在我正在将一个过滤数组传递给您给我的代码,但这实际上是两次搜索而不是一次。您对如何更有效地执行此操作有何建议?您真的建议循环所有可用的时间戳吗?正如我所说,这是效率低下的,但是我能想到的唯一解决方案。此外,您只循环通过时间戳,其中
entry
,不是整个对象/数组/任何东西。同样,也不是最好的,但它可以工作,也没有从A-Z循环数组那么糟糕。这取决于数组/对象的稀疏程度。时间戳以毫秒为单位:-)仍然是如此,即使对于OP提供的样本数据,我希望for in循环会快得多呃。如果没有找到任何东西,你的解决方案就不会被捕获,它将循环直到
-Infinity
。@Bergi修复了
-Infinity
错误;捕获得很好。我确实检查了你的东西;有趣的是,循环整个数组将比我的解决方案更好。将予以考虑;谢谢!
// for each entry:
var n2 = n;
while (typeof items[n2] == "undefined" && n2 >= -1) {
    n2--;
}
if (n != -1) {returnedArray[idBeingProcessed] = items[n2];}
else {alert("Error handling here");}
// repeat for each item (id 1, id 2...)