2

Consider the following:

var _processSupplementalData = function(supfData) {

    if (!supfData.length > 0) {
      return;
    }

    var sectionData = {
      label: supfData[0].label,
      supplementalLinks: [],
    }

    supfData.forEach(function(data, index, object) {
      sectionData.supplementalLinks.push(data);
      supfData.splice(index, 1);
    });

    //dataObservableArray.push(sectionData);

    console.log(sectionData);
}

my question is simple:

supfData is an array of 4 objects. With the code as it stands, the sectionData object, at the end of this, has a supplementalLinks array of size 2.

How ever if I remove the splice code, the supplementalLinks arry now has the proper size: 4.

How am I using splice wrong such that I only have 2 objects in the array instead of 4?

shift does the same thing for me.

What do I expect to happen?

Every an item is added to the array it needs to be removed from the array I am iterating over. If there are 4 objects in the array I am iterating over then here should be 4 objects in the sectionData.supplementalLinks array.

TheWebs
  • 12,470
  • 30
  • 107
  • 211
  • What do you expect splice to do? It removes items from the array while you are iterating over it – Ruan Mendes Mar 15 '16 at 02:43
  • If you *splice* within *forEach*, the elements are shuffled down one so it will skip the next element. – RobG Mar 15 '16 at 02:43
  • You remove that data in the iteration. – aldrin27 Mar 15 '16 at 02:44
  • Splice keeps mutating the array, the next element is at the old index position but the next iteration considers that the index isn't the old index but old index + 1. So it kind of double jumps values. – MinusFour Mar 15 '16 at 02:45
  • @RobG See the OP, I put what I expect to happen. If you think this is a duplicate, please link to a proper question that answers this. – TheWebs Mar 15 '16 at 02:48
  • @MinusFour I have put what I expect to happen in the OP. – TheWebs Mar 15 '16 at 02:50
  • @aldrin27 I need to remove the data in the iteration but ONLY after that particular piece of data has been added to the new array – TheWebs Mar 15 '16 at 02:50
  • @JuanMendes I have put what I expect i the OP – TheWebs Mar 15 '16 at 02:51
  • The simplest solution for you is to iterate backwards, using a regular for loop, that way, the part of the array that you're removing has already been visited and there won't be index shifting – Ruan Mendes Mar 15 '16 at 02:53
  • @JuanMendes Please post an answer I can vote on if you have on :) thanks. – TheWebs Mar 15 '16 at 02:54

1 Answers1

2

The problem is that you are mutating the array that you are iterating over. Therefore, after the first iteration, your array only has three items, and when it retrieves the second item from the array, it's retrieving it from the array that was modified.

If you can iterate backwards, then the problem goes away

for(var i=supfData.length - 1; i >-1; i++) {
  sectionData.supplementalLinks.push(data);
  supfdataCopy.splice(i, 1);
});
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • Cool, so now there's yet another answer to a question that's been asked and answered several times before. – RobG Mar 15 '16 at 03:01
  • The links explain why the issue occurs and ways to address it The first "solution" you posted doesn't fix the issue, the copy will behave exactly as the original (it will still skip the element after the spliced one, if there is one). – RobG Mar 15 '16 at 03:10