oezguensi
oezguensi

Reputation: 950

Filter array property of object without mutating the object itself

I would like to filter a property of an object without mutating the object.

let myObject = {
    propA: [1,2,3],
    propB: "foo"
}

Now I would like to do something like:

myObject.propA.filter(el => el === 2)

But this only returns a filtered array and I would have to write

myObject.propA = myObject.propA.filter(el => el === 2)

in order to change my object.

But that's exactly not what I want! I would like to generate a new filtered object without mutating the old one. Could someone help me out?

Upvotes: 0

Views: 765

Answers (3)

Mulan
Mulan

Reputation: 135207

You could write transform using destructuring assignment and spread argument

const transform = ({ a = [], ...rest }) =>
  ({ a: a .filter (el => el === 2)
   , ...rest
   })

const myObject =
  { a: [ 1, 2, 3 ]
  , b: "foo"
  }
   
console .log
  ( transform (myObject)
    // { a: [ 2 ], b: "foo" }
    
  , transform ({ a: [ 1, 2, 1, 2, 1, 2 ], b: "bar", c: "cat" })
    // { a: [ 2, 2, 2 ], b: "bar", c: "cat" }
    
  , transform ({ y: "z" })
    // { a: [], y: "z" }
  )

Upvotes: 1

iwaduarte
iwaduarte

Reputation: 1700

You could also clone the object and alter only the property of the new object.

let myObject = {
    propA: [1,2,3],
    propB: "foo"
}
let newObject = Object.create(myObject);
newObject.propA = myObject.propA.filter(el=> el ===2);

Upvotes: 1

Mark
Mark

Reputation: 92440

You can filter() the array, and then merge it with the original object to create a new one without mutating the original. Something like:

let myObject = {
    propA: [1,2,3],
    propB: "foo"
}
let propA = myObject.propA.filter(el => el === 2)
let newobj = {...myObject, propA}

// new Object
console.log("New:", newobj)

// old object unchanges
console.log("Old:", myObject)

Upvotes: 2

Related Questions