我有一个像这样的JSON对象:
"time1": {
"item1": "val1",
"item2": "val2"
},
"time2": {
"item1": "val3",
"item2": "val4"
}
...
time*
的值是new Date()
值,以毫秒为单位,因此time*
值的序列已排序。
现在我必须按时间搜索项目,如果该键不存在,我必须采用最接近的值。 我在对象中有数千个条目,我正在考虑二进制搜索,但我不知道该怎么做。
我无法使用经典方式middle = (right+left)/2
,因为中间值可能是undefined
。
我不能使用二叉树,因为我有一个我无法改变的定义结构。
由于
答案 0 :(得分:1)
问题在于你可以对中位数进行未定义,但是最简单的形式是你可以使用中间键json.length/2
,它不是最佳的但它可以工作。
接下来,您必须进行二进制搜索,同时保留每步的索引。
基本上你要检查的是索引,并决定是否按每个索引的值向右或向左移动。
如果你死路一条,搜索的时间不存在,你确实知道“邻居”,最后一次检查,if ((time_to_search - json[index-1]) > json[index+1] - time_to_search))
检查它离它更近,到index-1
或index+1
(这是O(1)
所以你很好),最终你可以返回json[index-1]
或json[index+1]
。
这对你有意义吗?
添加了一个小提琴,http://jsfiddle.net/QFTJ5/
注意:这不是一个完整的小提琴
答案 1 :(得分:0)
以下是您只读取数组中time
个后缀的方法:
var json = {
"time1": {
"item1": "val1",
"item2": "val2"
},
"time2": {
"item1": "val3",
"item2": "val4"
}
}
var values = [];
for (var i in json) {
values += i.substring(4);
}
现在,您可以对values
索引进行二分查找。
答案 2 :(得分:0)
假设
var times = {
"1367999303810": { // today at 9:48am
"item1": "val1",
"item2": "val2"
},
"1368000000000": { // today at 10am
"item1": "val3",
"item2": "val4"
}
}
我会编写类似这样的代码(请修复数学!)
function getNearest(findTime) {
for (var i=0;i<tArr.length;i++) {
window.console && console.log(new Date(findTime),new Date(tArr[i]))
if (findTime === tArr[i]) return findTime; // exact match
if (findTime >= tArr[i]) break; // pinpoint
}
if (i==tArr.length) return -1; // nothing found
if (i==tArr.length-1) return tArr[i]; // found the end
// here the time to find is greater than one of the array entries
var diff1 = Math.abs (findTime - tArr[i]), // distance from last entry
diff2 = Math.abs (tArr[i+1] - findTime); // distance to next entry
return diff1 === diff2 ? tArr[i+1] : // return the newest time
diff2 > diff1 ? tArr[i] : tArr[i+1]; // or the nearest
}
var tArr = [];
for (var t in times) tArr.push(parseInt(t));
tArr.sort();
var findTime = new Date(2013,4,8,9,50,0).getTime(); // today at 9:50
var time = getNearest(findTime);
if (time !=-1) window.console && console.log(times[time])