2

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

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

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

 var items = [
      { id: 1,
        history: {1234: 'open', 1256: 'in-use', 1289: 'reset', 1293: 'open'},
      { id: 2,
        history: {1230: 'open', 1290: 'in-use'},
      { id: 3,
        history: {1238: 'open', 1241: 'in-use', 1251: 'reset'}
 ]

我希望能够拥有这样的功能:

 getStatus(1260);

然后回来

 {1: 'in-use', 2: 'open', 3: 'reset'}

每个id,其状态是根据查询时间之前的最近历史记录传入的。

我完全不依赖这个数据结构。我还尝试让历史记录包含时间和状态的对象数组,但这意味着我每次都必须遍历整个数组。我最大的问题是我的头脑正在推动我使用 SQL 方法来执行此操作,但我被困在客户端 Javascript 中......

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

谢谢!

4

2 回答 2

2

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

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

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;
}
于 2013-01-17T00:16:21.477 回答
0

你可以使用一个循环:

// 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...)

如果找到答案,这将停止。它可能效率低下,但是嘿,它有效:-)

history此外,如果适用,请考虑为您的对象使用数组。

于 2013-01-17T00:21:24.017 回答