Соединение первого объекта возвращает TypeError: невозможно прочитать свойство undefined - PullRequest
3 голосов
/ 19 июня 2020

У меня есть такой массив:

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'}, { name: 'Product 02', groupID: '50403', delivery: 'bike'} ]

И этот L oop для удаления указанных c объектов:

for(var i=0, len=arrSession.length; i<len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

Если я удаляю последний объект , все работает нормально:

var getGroupID = 50403;
var getDelivery = bike;

Но если я удаляю первый объект:

var getGroupID = 50303;
var getDelivery = mail;

получаю ошибку:

TypeError: Cannot read property 'groupID' of undefined  

Почему так и как это решить?

Изменить:

Если есть только один объект, все в порядке.

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'} ]

Ответы [ 6 ]

5 голосов
/ 19 июня 2020

Попробуйте преобразовать groupId в целочисленный формат.

ex -:

for(var i=0, len=arrSession.length; i<len; i++) {
    if (parseInt(arrSession[i].groupID) == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}
1 голос
/ 19 июня 2020

Короткий ответ : Из-за синтаксиса для l oop. Initialization бывает только once. Вы пропустили обновление len после splicing.

для оператора ([initialExpression]; [condition]; [incrementExpression])

Решение : Как уже упоминалось в других ответах, вы можете break l oop (который будет работать, если вы добавляете только один элемент).

const arrSessionActual = [{
  name: 'Product 01',
  groupID: '50303',
  delivery: 'mail'
}, {
  name: 'Product 02',
  groupID: '50403',
  delivery: 'bike'
}];

function removeItem(arrSession, getGroupID, getDelivery) {
  for (var i = 0,
      len = arrSession.length; i < len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
      arrSession.splice(i, 1);
      len = arrSession.length; // This is missing
    }
  }

  console.log(arrSession);
}

removeItem(arrSessionActual.slice(), 50403, 'bike');
removeItem(arrSessionActual.slice(), 50303, 'mail');
1 голос
/ 19 июня 2020

Array.splice изменяет массив. Если вы удалите первый элемент, длина массива уменьшается на 1, но в l oop он все еще пытается получить доступ к следующему элементу, который может быть или не быть undefined. Поскольку здесь всего 2 элемента, arrSession[1] это undefined.

Вместо этого используйте фильтр, подобный этому:

var arrSession = [{
  name: 'Product 01',
  groupID: '50303',
  delivery: 'mail'
}, {
  name: 'Product 02',
  groupID: '50403',
  delivery: 'bike'
}]


var getGroupID = 50303;
var getDelivery = 'mail';



var filtered = arrSession.filter(session => session.id !== getGroupID && session.delivery !== getDelivery)

console.log(filtered)

Надеюсь, это поможет!

1 голос
/ 19 июня 2020

Довольно просто: вы выполняете итерацию с начала массива и соединяете массив с найденным. Теперь массив короче, чем сохраненная длина, и при любом доступе происходит сбой.

Вместо этого вы можете oop с конца.

var arrSession = [{ name: 'Product 01', groupID: '50303', delivery: 'mail' }, { name: 'Product 02', groupID: '50403', delivery: 'bike' }],
    getGroupID = 50303,
    getDelivery = 'mail',
    i = arrSession.length;

while (i--) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

console.log(arrSession);
1 голос
/ 19 июня 2020

Я думаю, это потому, что когда запускается l oop, он будет go до индекса 1. После удаления индекса 0 ваш l oop все равно будет пытаться запустить и искать индекс 1, второй объект, который уже был перемещен. Если вы поместите ключевое слово break в оператор if, ошибка должна быть исправлена.

for(var i=0, len=arrSession.length; i<len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
        break;
    }
}
0 голосов
/ 19 июня 2020
...