查找时间t

时间:2017-03-07 18:49:14

标签: javascript arrays search

给定一个数组,其元素是以下形式的对象:

{
    "description": "foo",
    "startTime": 0,
    "endTime": 100
}

我需要找到startTime <= t <= endTime

的所有元素
  • (endTime - startTime) >= 100,但时间差没有明确的上限,数组中每个对象的差异也不一定相同。 startTime可能是否定的。
  • arr[i].startTime <= arr[i + 1].startTime,但<{1}}的 必须如此。
  • endTime 唯一,甚至在给定的时间范围内也不一定。
  • 时间对应于视频中的毫秒数,可以轻松为一小时或更长时间。如果1小时视频的整个长度为100毫秒持续时间对象,那么要过滤36,000个数组元素。根据视频的不同,单个100ms的时间内可能会有十几个对象。

我目前的解决方案是一个简单的description电话:

Array.prototype.filter

据我所知,video.getCurrentTime((s) => { // library function; s=current time in seconds of the video const ms = Math.floor(s * 1000); const itemsAtTime = metadata.filter((o) => { // metadata is array of objects const start = o.startTime; const end = o.endTime; return start <= ms && ms <= end; }); // ... for (let obj of itemsAtTime) { // do stuff } }); 是作为线性搜索实现的。有没有更好的算法可以实现我的目标?也许是二元搜索的一些变体?

在我测试的2分钟演示视频/元数据中,大多数filter调用在大约0.7毫秒内完成。但是,其中一些需要1-5毫秒,而且我已经跟踪了一些极端异常值,如11毫秒甚至33毫秒。我的&#34;做东西&#34;循环通常在0.1ms内完成,重负载需要4ms,异常值在12ms。最糟糕的是,filter函数是异步的,通常在调用它和调用回调之间花费1-5ms,在50-60ms附近有大量负载,而异常值高达500ms。考虑到这个代码是在传递给getCurrentTime的函数中,在播放视频时间隔正在运行(目前间隔为250毫秒,但最终我认为我想使用100毫秒或更短的间隔) ,当我开始使用一小时以上的持续时间视频时,我很担心表现。

1 个答案:

答案 0 :(得分:1)

您可以进行二元搜索,找到startTime <= ms的第一个项目。然后,您可以从该索引开始线性过滤。这是我能想到的最好的。

所以,比如:

const binaryWhereMin = function(arr, ms) {
  // write your function that returns the index of first element start <= ms
};

let index = binaryWhereMin(arr, ms);
let result = arr.splice(index, arr.length).filter(/* your filter */);

我看不到更好的方法,因为结尾没有排序。

这里有一个binary search example。但你需要改变它而不是搜索一个特定的元素(它不会那么高效!但我相信它仍然比你的更好)。