4

I got an object array which looks like this:

const items = [
  {_id: "Tk2dc3fq99qZ7YdQQ", parent: "Dn59y87PGhkJXpaiZ", content: "one", context: "default"}
  {_id: "uK4MYJJGa6ra9e99v", parent: "Dn59y87PGhkJXpaiZ", content: "two", context: "default"}
]

Note: items is readonly as it comes from prop in a react component

And I want to update the content by a given object like this:

const changeThis = { _id: "uK4MYJJGa6ra9e99v", context: "info" }

So the object with the matching ID should get 'info' as new context value while keeping all other elements:

[
  {_id: "Tk2dc3fq99qZ7YdQQ", parent: "Dn59y87PGhkJXpaiZ", content: "one", context: "default"}
  {_id: "uK4MYJJGa6ra9e99v", parent: "Dn59y87PGhkJXpaiZ", content: "two", context: "info"}
]

Another example

And...

const changeThis = { _id: "uK4MYJJGa6ra9e99v", context: "info", content: "new" }

...should change context and content of the matching object:

[
  {_id: "Tk2dc3fq99qZ7YdQQ", parent: "Dn59y87PGhkJXpaiZ", content: "one", context: "default"}
  {_id: "uK4MYJJGa6ra9e99v", parent: "Dn59y87PGhkJXpaiZ", content: "new", context: "info"}
]

My attempt

So first of all I would use map() to iterate throught the array, but how do I update all other fields using changeThis-object? I tried to use assign() and keys() and I tried to ignore the _id-key:

items.map((item, index) => {
  if (item._id === changeThis._id) {
    Object.assign(
      {},
      ...Object.keys(item).map(k => (
        {
          [k]: changeThis.indexOf(k) > -1 && k !== '_id'
            ? changeThis[k]
            : item[k]
        }
    ))
  }
});
1
  • 1
    why not if (..) Object.assign(item, changeThis) ? Commented Dec 4, 2017 at 23:06

1 Answer 1

5

A simple function will suffice here; keep in mind that you will need to use let or var instead of const for items; map does not edit in place, but rather returns a new array. You could edit in place, but I would not necessarily recommend it.

items = items.map(item => {
  return (item._id === changeThis._id) ?
    { ...item, ...changeThis } :
    item
});

By spreading the contents of changeThis into the object after the keys of item, any keys appearing in changeThis will override those from item. Keys non-duplicate keys from either object will also appear in the final result.

Sign up to request clarification or add additional context in comments.

2 Comments

A one-liner with... four lines? ;)
I had had it in one line, and then realized it wasn't readable at all... I'll edit that, thanks 😅

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.