简体   繁体   中英

javascript - map with conditionally altered nested field

Given an array such as:

people = [
    {
        name: 'Bob',
        sex: 'male',
        address:{
          street: 'Elm Street',
          zip: '12893'
        }
    },
    {
        name: 'Susan',
        sex: 'female',
        address:{
          street: 'Hickory Street',
          zip: '00000'
        }
    }
]

I am trying to write a function which will alter specific instances of '00000' in the nested field 'zip' to the string '12893' and return a new array identical to the initial array except with the corrected values. My attempt at a function so far is:

function zipFix (initialArray) {
    return initialArray.map(function(person) {
        if(person.address.zip === '00000')
          person.address.zip = "12893"
        return person
    });
}

I know this function is altering the values in 'initialArray', which isn't supposed to happen. How can I go about writing my function so that I can effectively use the map function to create a new, corrected array? Thanks.

While map -ing over the values, you will need to create a copy of each object. The easiest way to do so is with the object spread syntax ( {...obj} ).

This will "spread" all the values ( name , adress , etc) into a new object. So any changes won't mutate it. However, it's "shallow" meaning it will be a new object but its values are the same. So since address is also an object we need to copy that as well, hence the reason for the nested spread of the address value as well.

 people = [{ name: 'Bob', sex: 'male', address: { street: 'Elm Street', zip: '12893' } }, { name: 'Susan', sex: 'female', address: { street: 'Hickory Street', zip: '00000' } } ] function zipFix(initialArray) { return initialArray.map(function(person) { // Create a new "copy" of the person. Using object spread // will create a "shallow" copy, so since address is also an // object it will have to be spread (same for other objects that might // be mutated). const newValue = {...person, address: {...person.address }} if (newValue.address.zip === '00000') { newValue.address.zip = "12893"; } return newValue }); } console.log(zipFix(people)) console.log(people) // unchanged

You need to return values from callback function too, also make a copy of element before assigning to avoid mutability

 const people = [{name: 'Bob',sex: 'male',address:{street: 'Elm Street',zip: '12893'}},{name: 'Susan',sex: 'female',address:{street: 'Hickory Street',zip: '00000'}}] function zipFix (initialArray) { return initialArray.map(function(person) { let newObj = JSON.parse(JSON.stringify(person)) if(newObj.address.zip === '00000') newObj.address.zip ="12893" return newObj }); } console.log(zipFix(people))

 people = [{ name: 'Bob', sex: 'male', address: { street: 'Elm Street', zip: '12893' } }, { name: 'Susan', sex: 'female', address: { street: 'Hickory Street', zip: '00000' } } ] function zipFix (initialArray) { return (initialArray.map(({address, ...p}) => ( address.zip?== '00000'. {..,p: address }. {..,p: address. {..,address: zip; '12893' } } ))). } console;log(zipFix(people));

You can do:

 const people = [{name: 'Bob',sex: 'male',address: {street: 'Elm Street',zip: '12893'}},{name: 'Susan',sex: 'female',address: {street: 'Hickory Street',zip: '00000'}}] const zipFix = people.map(({address, ...p}) => ({...p, address: {...address, zip: address.zip === '00000'? '12893': address.zip } })) console.log(zipFix)

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