0

Let's take a simple Array of Objects.

let objarray = [
        {
            type: 2,
            number: 4768
        },
        {
            type: 2,
            number: 3168
        }
];

And perform a simple map function

objarray.map((elem, i) =>  {
        if (i == 0) {
            elem.number = 1;
        }
        else {
            elem.number = 0;
        }
});

The result works as expected.

0 : {type: 2, number: 1}
1 : {type: 2, number: 0}

But now, what I am having to do is, repeat N amount of times the objects inside of the array. I've tried a few different functions to do this. Here's one:

function replicate(arr, times) {
    var al = arr.length,
        rl = al*times,
        res = new Array(rl);
    for (var i=0; i<rl; i++)
        res[i] = arr[i % al];
    return res;
}

It works as expected:

let objarray_repeat = replicate(objarray, 2);

0 : {type: 2, number: 4768}
1 : {type: 2, number: 3168}
2 : {type: 2, number: 4768}
3 : {type: 2, number: 3168}

But when I try to do the exact same map function on the replicated array as shown above,

objarray_repeat.map((elem, i) =>  {
        if (i == 0) {
            elem.number = 1;
        }
        else {
            elem.number = 0;
        }
});

The output is incorrect:

0 : {type: 2, number: 0}
1 : {type: 2, number: 0}
2 : {type: 2, number: 0}
3 : {type: 2, number: 0}

As stated, I've tried numerous different functions to try to change up how I am replicating the objects in the array, but no matter what I try I cannot get the map function to work properly once I've replicated!

What's the solution here for using map on a replicated array?

edit:

JSFiddle https://jsfiddle.net/t2xpq1cz/

bbruman
  • 667
  • 4
  • 20
  • 2
    You're pushing *references* to the same object into your array. So when you change `objarray_repeat[2]` you also change `objarray_repeat[0]`; likewise for indexes 1 and 3. Use `res[i] = { ...arr[i % al] }` to push a (shallow) copy of the object into the array instead – Nick Oct 01 '22 at 07:26
  • Sorry I couldn't find a better dupe. I'm sure there's one out there somewhere... – Nick Oct 01 '22 at 07:27
  • @Nick is right. The first item in the array gets updated the number as `1` and in the third iteration it again gets updated to `0`. Since item at index 0 and index 2 refer to the same object. – Amila Senadheera Oct 01 '22 at 07:31

1 Answers1

1

let objarray = [{
    type: 2,
    number: 4768
  },
  {
    type: 2,
    number: 3168
  }
];

let objarray_repeat = replicate(objarray, 2);


objarray_repeat = objarray_repeat.map((elem, i) => {
  return { ...elem,
    number: i === 0 ? 1 : 0
  }
});

console.log(objarray_repeat);



function replicate(arr, times) {
  let copyArr = [...arr];
  for (let i = 0; i < times; i++) {
    copyArr = [...copyArr, ...arr]
  }
  return copyArr;
}
Alan Omar
  • 4,023
  • 1
  • 9
  • 20