【问题标题】:Find all array elements for time t查找时间 t 的所有数组元素
【发布时间】:2017-03-07 18:49:14
【问题描述】:

给定一个数组,其元素是表单中的对象:

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

我需要找到 startTime <= t <= endTime 的所有元素。

  • (endTime - startTime) >= 100,但时间差没有明确的上限,数组中每个对象的差也不一定相同。 startTime 可以为负数。
  • arr[i].startTime <= arr[i + 1].startTime,但对于endTime不一定也是如此。
  • description不是唯一的,甚至不一定在给定的时间跨度内。
  • 时间对应于视频中的毫秒数,很容易达到一小时或更长时间。如果 1 小时视频的整个长度有 100 毫秒持续时间的对象,则需要过滤 36,000 个数组元素。根据视频的不同,一个 100 毫秒的时间跨度可能很容易有十几个对象。

我目前的解决方案是一个简单的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
  }
});

据我所知,filter 是作为线性搜索实现的。有没有更好的算法可以实现我的目标?也许是二分搜索的一些变体?

在我正在测试的 2 分钟演示视频/元数据中,大多数 filter 调用在大约 0.7 毫秒内完成。但是,其中一些需要 1-5 毫秒,我已经跟踪了一些极端异常值,例如 11 毫秒甚至 33 毫秒。我的“做事”循环通常在 0.1 毫秒内完成,重负载需要 4 毫秒,异常值需要 12 毫秒。最糟糕的是,getCurrentTime 函数是异步的,通常在调用它和调用回调之间需要 1-5 毫秒,负载在 50-60 毫秒左右,异常值超过 500 毫秒。考虑到此代码在传递给setInterval 的函数中,在播放视频时间隔运行(当前间隔为 250 毫秒,但最终我想我想使用 100 毫秒或更短的间隔),我当我开始使用时长超过一小时的视频时,我担心性能。

【问题讨论】:

  • 比线性时间更快的唯一方法就是完全无事可做。
  • @peteb 也许你可以去log(n),例如?这比线性 (n) 快。
  • @LuanNico 是的,但是他想要过滤的项目需要进行排序。如果它们没有以排序方式插入,那么你就有了这样的开销。
  • @peteb 它们按 startTime 排序。
  • @BrianS 这是一个关键的信息。集合的大小也是一个很好的信息。

标签: javascript arrays search


【解决方案1】:

您可以进行二分搜索以找到startTime &lt;= 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。但是您需要更改它以不搜索特定元素(它不会那么高效!但我相信它仍然比您拥有的更好)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    相关资源
    最近更新 更多