【问题标题】:Better method for checking between two items in array检查数组中两个项目的更好方法
【发布时间】:2013-03-15 17:25:58
【问题描述】:

我有一个这样的数组:

var data = [
    {
        "title" : "Title 1",
        "slideText" : "",
        "startTime" : 0
    },
    {
        "title" : "Title 2",
        "slideText" : "",
        "startTime" : 60
    },
    {
        "title" : "Title 3",
        "slideText" : "",
        "startTime" : 120
    }
];

我在 HTML5 视频上有一个 seeked 事件监听器。当用户寻找时,我需要检查他们在哪里,并确定他们在数组中的哪个索引。例如,他们寻求 72 秒,他们将在 array[1]

现在我有这个:

player.addEventListener("seeked", function(event)
{
    currentTime = player.currentTime;
    angular.forEach($scope.data, function(value, key)
    {
        if (currentTime >= $scope.data[key].startTime && currentTime <= $scope.data[key + 1].startTime)
        {
            $scope.$apply(function()
            {
                $scope.setActive(key);
            });
        }
    });
});

这一切都有效,直到寻找的时间到达数组的末尾并且$scope.data[key + 1].time 未定义。我应该如何处理这个?我的思绪现在没有走上正轨,我还没有喝咖啡:|

编辑

新功能工作

player.addEventListener("seeked", function(event)
{
    currentTime = player.currentTime;
    for (var i = 0; i <= $scope.data.length; i++)
    {
        if ($scope.data[i + 1] != undefined)
        {
            if (currentTime < $scope.data[i + 1].startTime)
            {
                $scope.$apply(function()
                {
                    $scope.setActive(i);
                });
                break;
            }
        }
        else
        {
            $scope.$apply(function()
            {
                $scope.setActive($scope.data.length - 1);
            });
        }
    }
}); 

【问题讨论】:

  • 添加结束时间变量,则不需要进行[key + 1]检查。这总是会在最后一个元素上出错。
  • 这是我想要避免的。这当然是一种选择,我想我可以以编程方式生成属性。这些数组在别处生成并提供给我

标签: javascript jquery arrays angularjs


【解决方案1】:

首先测试数组元素的存在。如果失败,其他测试将被忽略:

if ($scope.data[key+1] && currentTime>=$scope.data[key].startTime && currentTime<=$scope.data[key+1].startTime)

【讨论】:

  • 这消除了错误,但我仍然需要知道我在最后一个元素上。假设我寻求 130 并且最后一个元素的开始时间是 120。我仍然需要通知我在最后一个元素上
  • 然后为if ($scope.data[key+1])if ($scope.data.length&lt;=key) 运行单独的独立测试。或者停止使用angular.forEach 并构建一个您自己的基本for 循环,该循环在$scope.data.length-2 处停止。有很多方法可以做到这一点。
  • 它是导致问题的 [key+1]。在最后一项上,key + 1 始终未定义。
【解决方案2】:

您需要检查[key + 1] 以确保您不会尝试访问超出数组长度的元素。

player.addEventListener("seeked", function(event)
{
    currentTime = player.currentTime;
    angular.forEach($scope.data, function(value, key)
    {
        if ( ($scope.data[key+1] != undefined) && currentTime < $scope.data[key+1].startTime)
        {
           // this is the one we are after
           return false; // exit foreach
        } else {
          // we are on the last one.
        }
    });
});

【讨论】:

  • 每次我寻找时,我都会在这个的其他部分着陆。我想可能是因为即使第一部分为真,它仍然会循环
  • @Ronnie 是的,它会的,我添加了一个 return 语句来退出循环。
  • 我试过了...显然angular.forEach不支持这种事情github.com/angular/angular.js/issues/263我需要重新考虑一下
  • @Ronnie 将循环重写为普通的 foreach。实现这个逻辑会更快更容易。
  • 是的,我正在这样做。 breakreturn false 仍然没有退出循环。每次我寻找时,我都会在控制台中看到 setActive fn 被调用以及“last”。我更新了我的问题
【解决方案3】:

这是最终的解决方案

player.addEventListener("seeked", function(event)
{
    currentTime = player.currentTime;
    for (var i = 0; i <= $scope.data.length; i++)
    {
        if ($scope.data[i + 1] != undefined)
        {
            if (currentTime < $scope.data[i + 1].startTime)
            {
                $scope.$apply(function()
                {
                    $scope.setActive(i);
                });
                break;
            }
        }
        else
        {
            $scope.$apply(function()
            {
                $scope.setActive(i - 1);
            });
        }
    }
}); 

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 2018-02-21
    • 2012-05-16
    相关资源
    最近更新 更多