0

I am trying to remove an item from an Array using Splice method.

arrayFinalChartData =[{"id":"rootDiv","Project":"My Project","parentid":"origin"},{"1":"2","id":"e21c586d-654f-4308-8636-103e19c4d0bb","parentid":"rootDiv"},{"3":"4","id":"deca843f-9a72-46d8-aa85-f5c3c1a1cd02","parentid":"e21c586d-654f-4308-8636-103e19c4d0bb"},{"5":"6","id":"b8d2598a-2384-407a-e2c2-8ae56c3e47a2","parentid":"deca843f-9a72-46d8-aa85-f5c3c1a1cd02"}];
ajax_delete_id = "e21c586d-654f-4308-8636-103e19c4d0bb,deca843f-9a72-46d8-aa85-f5c3c1a1cd02,b8d2598a-2384-407a-e2c2-8ae56c3e47a2";

$.each(arrayFinalChartData, function (idx, obj) {
  var myObj = obj.id;                   
  if (ajax_delete_id.indexOf(myObj) >= 0) {                     
    var vararrayFinalChartDataOne = arrayFinalChartData.splice(idx, 1);
  }
});
console.log(arrayFinalChartData);

Please check at : http://jsbin.com/deqix/3/edit

Note : It does not complete the "last leg " of the loop. That means if I have 4 items, then it successfully executes 3 items. Same goes for 6,7...items.

I need to "REMOVE" few items and "PRESERVE THE BALANCE" in an array.

  • 2
    Just a remark: `splice` is not a jquery specific function, it's part of plain JavaScript. – UweB Jul 21 '14 at 20:12

3 Answers3

0

You can use for loop instead of $.each function:

alert('length before delete ' + arrayFinalChartData.length);
for (var i = arrayFinalChartData.length - 1; i >= 0; i--) {
    id = arrayFinalChartData[i].id;
    if(ajax_delete_id.indexOf(id) > -1){
        arrayFinalChartData.splice(i, 1);
    }
};

alert('length after delete ' + arrayFinalChartData.length);

Demo.

Walid Ammar
  • 4,038
  • 3
  • 25
  • 48
0

Complete edit :

After researching a bit, and console.logging a lot, I finally found where the issue is coming from ! It's actually quite simple, but very sneaky !

Theoretical explanation :

You are calling the splice function with the variable "idx", but remember that the splice function remaps / reindexes your array ! So, each time you splice the array, its size decreases by one while you're still inside the $.each function. The splice messes up jQuery indexation of your array, because jQuery doesn't know that you're removing elements from it !

Iterative explanation :

$.each function starts, thinking your array has 4 elements, which is true, but only for a while. First loop, idx = 0, no splice. Second loop, idx = 1, splice, which means that your array has now 3 elements left in it, reindexed from 0 to 2. Third loop, idx = 2, splice, which means your array has now two elements left in it, but $.each continues ! Fourth loop, idx = 3, js crashes, because "arrayFinalChartData[3]" is undefined, since it was moved back each time the array got spliced.

To solve your problem, you need to use a for loop and to start analyzing the array from the end, not from the beginning, hence each time you splice it, your index will decrease as well. And if you want to preserve balance, just push the removed items into an array. Remember that you are analyzing the array from the end, so items pushed into the "removedItems" array will be in reverse order. Just like this :

var removedItems = new Array();

for (var i = arrayFinalChartData.length - 1; i >= 0; i--) {

    var myObj = arrayFinalChartData[i].id;

    if (ajax_delete_id.indexOf(myObj) >= 0) {

        removedItems.push(arrayFinalChartData.splice(i, 1)[0]);

    }

}

console.log(arrayFinalChartData);
console.log(removedItems);

And a working demo (inspect the page, observe the console and click "Run") :

http://jsfiddle.net/3mL6C/3/

I will not give credit to myself for this answer, thanks to another similar thread for giving me a hint.

Community
  • 1
  • 1
user3856210
  • 270
  • 2
  • 12
  • I need to "REMOVE" few items and "PRESERVE THE BALANCE" in an array using SPLICE. – user973310 Jul 20 '14 at 08:02
  • 1
    I don't really get what you mean with "PRESERVE THE BALANCE". Does that mean you want to have on one side an array with the DELETED elements, and on the other side an array with the PRESERVED elements ? – user3856210 Jul 20 '14 at 09:15
  • Actually, the array maintains the residual after the Splice method. The left hand Array only reflects the removed item. I may have 50 items in the array. I need to remove only 5 of them. I need to know the balance 45 items. My code works, except for the last item in the loop to be removed. – user973310 Jul 21 '14 at 02:59
  • 1
    Thanks for the effort and explanation. Though I had doubt the shifting index, I could not figure out the solution. Thanks again. – user973310 Jul 22 '14 at 02:05
0

Your problem here is that when the $.each is set up, it's expecting a certain length of object, which you are then changing. You need to loop in a way that respects the dynamic length of the object.

var i = 0;  
while (i < arrayFinalChartData.length) {
  var myObj = arrayFinalChartData[i].id;

  if (ajax_delete_id.indexOf(myObj) >= 0) {
     // current item is in the list, so remove it but KEEP THE SAME INDEX
     arrayFinalChartData.splice(i, 1);
  } else {
    // item NOT in list, so MOVE TO NEXT INDEX
    i++
  }

}

console.log(arrayFinalChartData);

Demo

Evan Davis
  • 35,493
  • 6
  • 50
  • 57