0

there. I am recently learning JS and I get into the trouble, rn. I use this method to overwrite values:

const person1 = {name: 'Jack', age: 10, job: 'developer'}
const person2 = {name: 'Su', age: 20}
const person3 = {name: 'Jin', job: 'singer'}
const result = {...person1, ...person2, ...person3} // {name: 'Jin', age: 20, job: 'singer'}

However, what if there is another object(array) inside object? For instance:

const person1 = {name: 'Jack', age: 10, job: 'developer', hobbies: [{a:'baseball'}, {b:'basketball'}]}
const person2 = {name: 'Su', age: 20}
const person3 = {name: 'Jin', job: 'singer', hobbies: [a:'sing']}
const result = {...person1, ...person2, ...person3} // {name: 'Jin', age: 20, job: 'singer', hobbies: [a:'sing']}

I would like to keep the original values of hobbies and overwrite only one of them. It looks like I have to use spread operator like I have used before, but I have no idea how and where to use it. Is there any way or better approach to solve this issue?

6
  • Can you provide a little more context for what you're trying to accomplish? Are you trying to combine the hobbies arrays from the different people? Also, I'm not sure if this is part of what confused you, but when you spread all three objects into the same result object, the keys in later objects overwrite the same keys in earlier objects. That's why your result only shows key/value pairs from person 3. Commented Apr 14, 2023 at 2:55
  • @ZacharyDuvall yes, I am trying to combine hobbies arrays from person3 to person1. I am aware why this is happening, but I do not know how to combine them. Commented Apr 14, 2023 at 3:55
  • Do you want to keep all hobbies? There are 2 hobbies with key 'a' in your example. What do you expect in this case? Also overwrite them or assign new keys to the ones with same key? Commented Apr 14, 2023 at 4:34
  • @Eriksen I would like to keep hobbies. person1 has 'a' key in hobbies and person3 has 'a' key as well. What I want is that change the value of 'a' key in person1 to person3. So, the result should be {name: 'Jin', age: 20, job: 'singer', hobbies: [{a: 'sing'}, {b: 'basketball'}}. They have a unique id for each object in hobbies array which I forgot to put. sorry :( Commented Apr 14, 2023 at 6:05
  • @LeeSeongBae ok, I also noticed that in person3, there is only one hobbie and it is not inside an object. This is how you have the data of it was a mistake? Commented Apr 15, 2023 at 1:38

1 Answer 1

1

I think this may be what you're going for. If you're okay with changing hobbies to an object rather than an array of objects, it's a lot simpler.

const isObject = (el) =>
  typeof el === 'object' && !Array.isArray(el) && el !== null;

const person1 = {
  name: 'Jack',
  age: 10,
  job: 'developer',
  hobbies: { a: 'baseball', b: 'basketball' },
};
const person2 = { name: 'Su', age: 20 };
const person3 = { name: 'Jin', job: 'singer', hobbies: { a: 'sing' } };

const people = [person1, person2, person3];

const res = {};

for (const person of people) {
  for (const [k, v] of Object.entries(person)) {
    if (k in res && isObject(v)) {
      res[k] = { ...res[k], ...v };
    } else {
      res[k] = v;
    }
  }
}

console.log(res)
// {
//   name: 'Jin',
//   age: 20,
//   job: 'singer',
//   hobbies: { a: 'sing', b: 'basketball' }
// }

Now all of the later keys overwrite the earlier keys, including within the hobbies object. If you wanted, you could also make something like this recursive for further nested objects.

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

4 Comments

Thank you for your answer! but the data I have are arrays on hobbies and there are objects inside arrays of hobbies. :(
Thanks for the response. It's a strange practice to store an array objects where all objects in the array have unique keys. An object by definition is a bunch of key/value pairs where all keys are unique, so the array just adds an unnecessary level of complexity. Wherever you're creating the data, I'd strongly recommend switching to creating a single object rather than appending single-key objects into an array.
If you really can't switch, you can use a similar approach to above, but rather than using isObject(v), just use Array.isArray(v), and then you'll have to iterate through the hobbies list in res[k] and compare it against the hobbies list in v and replace old ones with the new ones if they have the same key. Unfortunately you can't just spread the lists together like you can with objects to achieve your desired outcome... That would just combine them and keep everything: [...[{a:'baseball'}, {b:'basketball'}], ...[{a:'sing'}]] = [{a:'baseball'}, {b:'basketball'}, {a:'sing'}]]
because I am using a tree. To use the tree, I needed a children which was a group of objects. and you too, thanks for your response !! :):)

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.