2

これは 1 行の質問で表現するのはちょっと難しいですが、データを構造化し、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 に答える