插入有序数组的大多数计算效率高的方法?

时间:2014-01-06 08:12:12

标签: javascript jquery arrays performance

我有一个包含时间序列数据的数组,如下所示:

var timeseries = [
    [Tue Dec 31 2013 00:00:00 GMT+0000 (GMT Standard Time), 3, 2],
    [Tue Dec 31 2013 01:00:00 GMT+0000 (GMT Standard Time), 1.2, 3],
    [Tue Dec 31 2013 02:00:00 GMT+0000 (GMT Standard Time), 4, 2]
]

嵌套数组中的第一项是javascript日期。

我有第二个数组,其中包含一个唯一的javascript日期列表,但 timeseries 数组中可能已存在或未存在:

var newTimes = [
    Tue Dec 31 2013 00:13:00 GMT+0000 (GMT Standard Time), 
    Tue Dec 31 2013 01:00:00 GMT+0000 (GMT Standard Time), 
    Tue Dec 31 2013 01:40:00 GMT+0000 (GMT Standard Time)
]

对于 newTimes 数组中的每个项目,我需要检查存储在 timeseries 数组中的数组中是否存在该日期。如果没有,我想在正确的位置(按时间顺序)将新数组插入到timeseries数组中,并且 - 至关重要的是 - 从前面的数组中复制其他数组值。例如,如上所述组合上述两个数组就可以了:

var newTimeseries = [
    [Tue Dec 31 2013 00:00:00 GMT+0000 (GMT Standard Time), 3, 2],
    [Tue Dec 31 2013 00:13:00 GMT+0000 (GMT Standard Time), 3, 2],
    [Tue Dec 31 2013 01:00:00 GMT+0000 (GMT Standard Time), 1.2, 3],
    [Tue Dec 31 2013 01:40:00 GMT+0000 (GMT Standard Time), 1.2, 3],
    [Tue Dec 31 2013 02:00:00 GMT+0000 (GMT Standard Time), 4, 2]
]

我应该注意两个数组都已经排序了。此外, newTimes 中的项目将存在于 timeseries 的范围内。最后,原始的 timeseries 数组每小时都有一个条目。

我尝试了几种不同的方法,但我对计算效率最高的方法很感兴趣。我很乐意使用任何适当的良好采用的第三方库,如underscore.js,如果有帮助的话。

1 个答案:

答案 0 :(得分:1)

考虑过二元搜索(由评论中的techfoobar提出)和冒泡排序(friendzis),到目前为止我提出的最佳解决方案是遵循这个逻辑。

与使用二进制搜索相反,请考虑以下内容。

因为我们知道两个数组都已经排序; newTimes内的日期属于timeseries个日期的范围;并且初始timeseries条目在小时,每小时,我们可以找到时间序列[0] [0]日期和新时间[0]之间的小时差异。这是启动冒泡排序方法所需的初始偏移量(更像是上面注释中讨论的标准循环和切片)。这使用Moment.js库。

下面的代码,请随时提出更改建议:

var firstEvent = moment(newTimes[0]);
var firstTime = moment(timeseries[0][0]) ;
var offset = firstEvent.diff(firstTime, 'hours') - 1; 


for (var i = offset; i < timeseries.length;i++) { 
    while (newTimes.length > 0 && typeof moment(timeseries[i+1]) !== "undefined" && moment(newTimes[0])  > moment(timeseries[i][0]) && moment(newTimes[0])  < moment(timeseries[i+1][0])) {
        var newElement = timeseries[i].slice(0);
        newElement[0] = moment(newTimes[0]).toDate();
        timeseries.splice(i+1, 0, newElement);
        newTimes.splice(0,1);
        i++;
    } 
}

重要的是,当newTimes数组中有两个或多个条目都属于一个timeseries条目时,这可以解决边缘情况,例如:

var timeseries = [
    [Tue Dec 31 2013 00:00:00 GMT+0000 (GMT Standard Time), 3, 2],
    [Tue Dec 31 2013 01:00:00 GMT+0000 (GMT Standard Time), 1.2, 3]
]

var newTimes = [
    Tue Dec 31 2013 00:13:00 GMT+0000 (GMT Standard Time), 
    Tue Dec 31 2013 00:16:00 GMT+0000 (GMT Standard Time)
]