admin 管理员组

文章数量: 1086019

I have an array like this:

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

And this Loop to delete specific objects:

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

If I'm deleting the last object, all works fine:

var getGroupID = 50403;
var getDelivery = bike;

But if I'm deleting the first object:

var getGroupID = 50303;
var getDelivery = mail;

I get an error:

TypeError: Cannot read property 'groupID' of undefined  

Why so and how to solve it?

Edit:

If there is only one object all is fine too.

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

I have an array like this:

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

And this Loop to delete specific objects:

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

If I'm deleting the last object, all works fine:

var getGroupID = 50403;
var getDelivery = bike;

But if I'm deleting the first object:

var getGroupID = 50303;
var getDelivery = mail;

I get an error:

TypeError: Cannot read property 'groupID' of undefined  

Why so and how to solve it?

Edit:

If there is only one object all is fine too.

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'} ]
Share Improve this question asked Jun 19, 2020 at 17:24 Philipp MPhilipp M 3,5085 gold badges43 silver badges101 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 1

Short Answer: Due to the for loop syntax. Initialization happens only once. You missed to update len after splicing.

for ([initialExpression]; [condition]; [incrementExpression]) statement

Solution: As already mentioned in the other answers, you can break the loop (which will work if you are spicing only one item).

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');

I think this is because when the loop starts, it will go up to index 1. After you delete index 0, your loop will still try to run and search for index 1, the second object, which has already been moved. If you put a break keyword in the if statement, the error should be fixed.

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

Pretty simple, you iterate from the start of the array and you splice the array on found. The array is now shorter than the stored length and any access goes wrong.

You could loop from the end instead.

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);

Try it converting 'groupId' to integer format.

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);
    }
}

Array.splice mutates the array. If you remove the first element, the array length decreases by 1 but in the loop it still tries to access the next element which may or may not be undefined. Here since there are only 2 elements the arrSession[1] is undefined.

Instead use filter like this :

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)

Hope this helps !

本文标签: javascriptSplicing first object returns TypeError Cannot read property of undefinedStack Overflow