0
const words = [{ref : "a", list: "a & b & c & d", total: 0},
              {ref : "a", list: "a & b & c & d", total: 0},
              {ref : "b", list: "aa & bb & cc & dd", total: 0},
              {ref : "c", list: "aaa & bbb & ccc & ddd", total: 0}];

 var data = words.filter(item => {
            if (item.ref == "a")
              return item;
        });

let result = data.map(o => {
            o.list = o.list.split('&').map(key => ({
                selected: false,
            }))
            return o;
        });
console.log(words);
console.log(result);
  • I have words array
  • after filtering for ref : a i'm getting new array data
  • but when i modifiy the data's object it is reflecting on main array words's. which should not happen.
words
> Array [
Object { ref: "a", list: Array [Object { selected: false }, Object { selected: false }] },
Object { ref: "a", list: Array [Object { selected: false }, Object { selected: false }] },
Object { ref: "b", list: "aa & bb" },
Object { ref: "c", list: "aaa & bbb" }
]

result
> Array [
Object { ref: "a", list: Array [Object { selected: false }, Object { selected: false }] },
Object { ref: "a", list: Array [Object { selected: false }, Object { selected: false }] }
]
  • In words you can see ref b and ref c is not modified
  • but ref a is changed. which should not happen in my case

* How to avoid alteration of original array words ? *

Vikas Acharya
  • 3,550
  • 4
  • 19
  • 52
  • `map` returns a new array. But, here `o.list = o.list.split()` you are modifying the objects inside the array. You can change it to something like `data.map(o => ({ ...o, list:o.list.split('&') }) )`. Also, you can simplify filter to: `words.filter(item => item.ref == "a")` – adiga May 18 '20 at 09:43

1 Answers1

1

Your .map() call changes the list property of the original object. map() returns a new array, but if you change the objects inside it directly, they are affected. Objects are always passed by a reference.

To prevent your map() changing the original array, you need to return a copy of each element:

let result = data.map(o => ({
    ...o,
    points: 10,
    list: o.list.split('&').map(key => ({
        selected: false,
    }))
}));

Of note, you also use filter() wrong. In filter(), you should return true or false to, respectively, keep or reject an element. It's enough to return the result of your condition:

var data = words.filter(item => {
    return item.ref == "a";
});
Robo Robok
  • 21,132
  • 17
  • 68
  • 126