foreach循环递减索引中的JavaScript拼接函数
这是我从数组中删除“完成”TODO的代码, 但是,如果删除彼此后面的两个TODO,则只删除第二个TODO。foreach循环递减索引中的JavaScript拼接函数,javascript,angularjs,Javascript,Angularjs,这是我从数组中删除“完成”TODO的代码, 但是,如果删除彼此后面的两个TODO,则只删除第二个TODO。 我认为这是因为splice函数重置并返回拼接的数组。您将数组中的元素拼接在一起,然后进行迭代,因此减少了“TODO”中的索引。对不起,我的英语不好 $scope.clearCompleted = function() { angular.forEach($scope.todos, function(todo, i) {
我认为这是因为splice函数重置并返回拼接的数组。您将数组中的元素拼接在一起,然后进行迭代,因此减少了“TODO”中的索引。对不起,我的英语不好
$scope.clearCompleted = function()
{
angular.forEach($scope.todos, function(todo, i)
{
if(todo.done)
{
$scope.todos.splice(i, 1);
}
});
if($scope.todos.length == 0)
{
$scope.isEmpty = true;
}
}
这是因为
forEach
只知道数组的初始状态,因此调用您的方法两次,即使第一次调用从数组中删除了一个项。只需执行一个简单的while循环即可:
var notDonedTodos = [];
angular.forEach($scope.todos, function(todo, i)
{
if(!todo.done)
{
notDonedTodos.push(todo);
}
});
$scope.todos = notDonedTodos;
每次
迭代的问题是,它从数组中删除一个项,从而导致跳过迭代。jQuery有一个很好的grep
方法,该方法返回符合由提供的匿名函数确定的特定条件的所有元素
var i = $scope.todos.length;
while (i--){
if ($scope.todos[i].done){
$scope.todos.splice(i, 1);
}
}
工作示例
作为另一种选择,您可以在每次执行
拼接时减小索引。例如:
var todos =[{id:1, done:false},{id:2, done:true},{id:3, done:true}];
function removeCompleted(todos){
return $.grep(todos,function(todo){
return todo.done == false;
});
}
todos = removeCompleted(todos);
console.log(todos);
这将在每次修改数组时调整索引以保持其有效性。您仍然可以使用angular.forEach
,并且不会得到两个数组副本。我发现自己的替代方法是使用array.filter方法。这是基于对象键过滤数组的最简单方法。如果你正在从事IE8项目(可怜的你),你需要为这个函数添加一个polyfill,因为它对JavaScript来说是相当新的
应答码:
$scope.clearCompleted = function() {
angular.forEach($scope.todos, function(todo, i) {
if(todo.done) {
$scope.todos.splice(i, 1);
i--;
};
});
if($scope.todos.length == 0) {
$scope.isEmpty = true;
};
}
是的,.splice()
会变异数组。如果使用正向迭代,则需要考虑到这一点。值得指出的是,此解决方案的诀窍在于数组是按相反顺序处理的,因此我们可以忽略数组长度的波动性。这同样适用于传统的for循环。
$scope.clearCompleted = function() {
$scope.todos = $scope.todos.filter(function(item) {
return !item.done;
});
}