angularjs forEach и соединение
у меня есть такой массив:
$scope.emails = [
  {"key":"Work","value":"user@domine.com"},
  {"key":"","value":""},
   {"key":"Work","value":"user2@domine.com"}
  {"key":"","value":""}];
Итак, я хочу удалить пустые письма, но и угловые forEach метод удаления только одного объекта, который является последним объектом почему???.
код js
angular.forEach($scope.emails, function(email, index){
     if(email.value ===""){
       $scope.emails.splice(index, 1);
     } 
    });
где я делаю не так
6 ответов
проблема в том, что вы удаляете элементы из массива во время цикла, поэтому более поздние элементы имеют разные индексы. Вместо этого вам нужно сделать петлю назад:
for (var i = $scope.emails.length - 1; i >= 0; i--) {
    if (!$scope.emails[i].value) {
        $scope.emails.splice(i, 1);
    }
}
здесь обновленный пример.
как указывали другие, виновником кода является удаление массива. Чтобы обойти с угловым.forEach, вы можете попробовать подход добавления/назначения:
var filteredEmails = [];
angular.forEach($scope.emails, function(email, index){
    if(email.value !==""){
        filteredEmails.push(email);
    }
});
$scope.emails = filteredEmails;
indexOf возвращает -1 когда он не находит элемент.
способ удалить элемент и избежать удаления последнего, когда он не найден, это:
var index = $scope.items.indexOf($scope.oldItem);
if (index != -1) {
  $scope.items.splice(index, 1);
}
describe('Foreach Splice', function () {
  it('splicing', function () {
    var elements = [
      {name: "Kelly", age: 16},
      {name: "", age: 17},
      {name: "Becky", age: 18},
      {name: "", age: 18},
      {name: "Sarah", age: 19},
      {name: "", age: 20},
      {name: "", age: 22},
      {name: "Mareck", age: 21},
      {name: "", age: 21},
      {name: "Mareck", age: 21}
    ];
    removeEmptyEntry(elements);
    console.log(elements);
  });
  function removeEmptyEntry(elements) {
    elements.forEach(function (element, index) {
      if (!element.name) {
        elements.splice(index, 1);
        removeEmptyEntry(elements);
      }
    });
  }
});
Я не пробовал это с AngularJs, но с Angular 4 аналогичный способ этого работает довольно хорошо.
angular.forEach($scope.emails, function(email){
 if(email.value ===""){
   $scope.emails.splice($scope.emails.indexOf(email), 1);
 } 
});
угловая версия 4:
this.emailArray.forEach(email => {
  if (email.value == "") {
    this.emailArray.splice(this.emailArray.indexOf(email),1);
  }
});
по словам docs, функция итератора позволяет третий параметр, который является коллекция, которая повторяется. Сращивание этой коллекции вместо $scope.emails удалит ожидаемый obejct.
angular.forEach($scope.emails, function(email, index, obj){
    if(email.value ===""){
        obj.splice(index, 1);
    } 
});