0

I have a function that processes arrays, and puts them into a specific format at the end. I do this by cycling through the processed-but-not-formatted output, formatting it into a JSON and pushing it to an array. However, when I push it to the array, every other item already in the array changes to be what I've just pushed. Why, and how can I fix this? It's probably something silly that I missed, but I can't figure out the cause of the issue.

function removeLastXItems(newArr, i, format, key){
  newArr.splice(newArr.length-i-1, i);
  var toInsert, finalArr = [];
  for (b=0;b<newArr.length;b++){
    toInsert = format;
    toInsert[key] = newArr[b];
    finalArr.push(toInsert);
    console.log(finalArr)
  }
  return finalArr;
}

When I run removeLastXItems(["foo", "bar", "fob", "bof", "far", "boo"], 2, {itGoes:"here", andNot:"here"}, "itGoes"), I'd expect the output to be:

[
  { itGoes: "foo",
    andNot: "here"
  },
  { itGoes: "bar",
    andNot: "here"
  },
  { itGoes: "fob",
    andNot: "here"
  },
  { itGoes: "bof",
    andNot: "here"
  }
]

However, the actual output is:

[ 
  { itGoes: 'boo', 
    andNot: 'here' },
  { itGoes: 'boo', 
    andNot: 'here' },
  { itGoes: 'boo', 
    andNot: 'here' },
  { itGoes: 'boo', 
    andNot: 'here' } 
]

Clearly, the result is changing, as if I look in the console I see:

[ 
  { 
    itGoes: 'foo', 
    andNot: 'here' 
  } 
]

[ 
  { 
    itGoes: 'bar', 
    andNot: 'here' 
  },
  { 
    itGoes: 'bar', 
    andNot: 'here' 
  } 
]

[
  { 
    itGoes: 'fob', 
    andNot: 'here' 
  },
  { 
    itGoes: 'fob', 
    andNot: 'here' 
  },
  { 
    itGoes: 'fob', 
    andNot: 'here' 
  } 
]

[ 
  {
    itGoes: 'boo', 
    andNot: 'here' 
  },
  { 
    itGoes: 'boo', 
    andNot: 'here' 
  },
  { 
    itGoes: 'boo', 
    andNot: 'here' 
  },
  { 
    itGoes: 'boo', 
    andNot: 'here' 
  } 
]

as obvious, the other items in the array are changing each time I push!

I've looked at this similar post, but I've not committed any of the mistakes outlined in the answers there. Therefore, if someone can find my mistake, I'd greatly appreciate it!

Geza Kerecsenyi
  • 1,127
  • 10
  • 27
  • *"I've looked at this similar post, but I've not committed any of the mistakes outlined in the answers there."* You have, actually. :-) `toInsert = format;` doesn't create a new object, it just makes the variable `toInsert` point to the same object that `format` points to. To create a *new* object, either use an object initializer (`toInsert = {}`) (or a constructor function with `new`, but in this case, probably the object initializer). It's not clear what you're trying to do with `format`, though. Are you trying to make the new objects copies of it, or...? – T.J. Crowder Jan 08 '19 at 14:03
  • If you're trying to make copies, a *shallow* copy can be done via [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) (you'll need a polyfill for older environments): `toInsert = Object.assign({}, format);`. For a *deep* copy, see [this question's answers](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript). – T.J. Crowder Jan 08 '19 at 14:05
  • Thanks; why are these comments not answers though? – Geza Kerecsenyi Jan 08 '19 at 16:13
  • The *answers* are in the answers to the linked question. The comments above are just to help you relate those answers to your particular situation, and in the case of the copying stuff, to try to proactively help you with what might be your next question. :-) – T.J. Crowder Jan 08 '19 at 16:20

0 Answers0