简体   繁体   中英

React/js- copy array and edit without editing original array

I am trying to filter an array, pass results in new array and edit new array without changes in the original array.

Code looks like this:

 const personalDocs = [{ "IDcard": false, "passport": true, "documentnumber": "1", "dateofissue": "" }, { "IDcard": true, "passport": false, "documentnumber": "2", "dateofissue": "" }]; const passports = personalDocs.filter((doc) => doc.passport === true); const passportsCollection = [...passports]; // tried: const passportsCollection = passports.slice() passportsColection.forEach(object => { delete object['IDcard']; object.taken = "YES"; }); console.log("ALL PERSONAL DOCS:") console.log(personalDocs) // this becomes same as passportsCollection :( console.log("JUST PASSPORTS") console.log(passportsCollection)

Live code available here: https://codesandbox.io/s/agitated-wilson-p9w8kt?file=/src/App.js

Is this related to javascripts basics or react?

Thank you.

This line doesn't do what you think it does:

const passportsCollection = [...passports];

It doesn't clone the items. It creates a copy of the array, but with references to the same objects.

Why? Because objects are passed by reference. So each item in each of the two arrays will be a reference to the same (base) object.

To clone the objects you need to spread each of them:

const passportsCollection = passports.map(i => ({ ...i }));

See it working:

 const personalDocs = [{ "IDcard": false, "passport": true, "documentnumber": "1", "dateofissue": "" }, { "IDcard": true, "passport": false, "documentnumber": "2", "dateofissue": "" } ]; const passports = personalDocs.filter((doc) => doc.passport === true); const passportsCollection = passports.map(i => ({ ...i })); // tried: const passportsCollection = passports.slice() passportsCollection.forEach(object => { delete object['IDcard']; object.taken = "YES"; }); console.log("ALL PERSONAL DOCS:") console.log(personalDocs) // this becomes same as passportsCollection :( console.log("JUST PASSPORTS") console.log(passportsCollection)

Another problem you had was you missed an l when typing passportsCollection .


On a separate note, what you're doing could be streamlined to:

const passportsCollection = personalDocs
  .filter(o => o.passport)
  .map(({ IDcard, ...o }) => ({ ...o, taken: 'YES'}))

 const personalDocs = [{ "IDcard": false, "passport": true, "documentnumber": "1", "dateofissue": "" }, { "IDcard": true, "passport": false, "documentnumber": "2", "dateofissue": "" } ]; console.log({ personalDocs, passportsCollection: personalDocs .filter(o => o.passport) .map(({ IDcard, ...o }) => ({ ...o, taken: 'YES'})) })

It's related to JavaScript basics.

You copied the array, but you didn't copied the object inside of the array.

const copy = passports.map(object => ({ ...object})

Notice that .map and .filter already create a copy of an array so you don't need to do `[...passports]

You can also try using structuredClone

You can use map directly with filter instead of forEach in order to create a new array. you can destruct the object to remove IDcard instead of using delete keyword

.map(({
  IDcard,
  ...object
})

See snippet below

 const personalDocs = [{ IDcard: false, passport: true, documentnumber: "1", dateofissue: "" }, { IDcard: true, passport: false, documentnumber: "2", dateofissue: "" } ]; const passports = personalDocs.filter(doc => doc.passport).map(({ IDcard, ...object }) => ({ ...object, taken: 'YES' })); console.log("ALL PERSONAL DOCS:"); console.log(personalDocs); console.log("JUST PASSPORTS"); console.log(passports);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM