4

I want to have a immutable original array of object and extend a new one, but seems the code below did nto produce the right result. obj3 became an object instead of an array of object. I even tried lodash's extend.

var obj1 = [{
  abc: 'abc value'
}, {
  def: 'def value'
}];

var obj2 = {
  def: 'new def value'
};

/*var obj3 = _.extend({}, obj1, obj2);
console.log(obj3)
*/

var obj3 = Object.assign({},obj1,obj2);

https://jsbin.com/bawadeqicu/edit?html,js,output

My desire output is

obj1: [{"abc":"abc value"},{"def":"def value"}] // immutable
obj3: [{"abc":"abc value"},{"def":"new def value"}]
3
  • 3
    Clone the array and assign obj2 as the second element of the new copy. There is no "pretty" way to do this. var obj3 = obj1.slice(); obj3[1] = obj2;. I mean, you could do var obj3 = Object.assign([], obj1, {1: obj2}); but that seems more magic ¯\_(ツ)_/¯ Commented Jan 6, 2017 at 23:35
  • check this link github.com/rtfeldman/seamless-immutable/issues/43 Commented Jan 7, 2017 at 0:02
  • 1
    Why is the second object updated? Because it has a property def? Do you want to match/merge objects based on property? What should happen if the property name was different? would obj2 simply be added to the array? Would the objects be merged in a different? What if both objects in the array had the same property? What if they have other properties as well? You haven't actually described what the merge rules are so any answer you get will just be an interpretation based on the specific input and output you provided. Commented Jan 7, 2017 at 0:53

2 Answers 2

2

Going immutable

Instead of passing the object and mutating it, we will be better off creating a completely new object:

const person = {
  name: 'John',
  age: 28
}
const newPerson = Object.assign({}, person, {
  age: 30
})
console.log(newPerson === person) // false
console.log(person) // { name: 'John', age: 28 }
console.log(newPerson) // { name: 'John', age: 30 }

source

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

3 Comments

You should elaborate on this; link-only answers are frowned on here since the link may not survive the passage of time.
@Jacob you mean i should write the answer and refer to the link too ??
I want array of object,not just object.
2

You can use Object.entries(), .map() spread element at obj1 parameter passed to Object.assign() to spread the object elements of obj1 array to the new array.

var obj1 = [{
  abc: 'abc value'
}, {
  def: 'def value'
}];

var obj2 = {
  def: 'new def value'
};

var obj3 = Object.entries(Object.assign({},...obj1, obj2))
           .map(([prop, value]) => ({[prop]:value}));

console.log(
  `obj1:${JSON.stringify(obj1)}`
  , `\nobj2:${JSON.stringify(obj2)}`
  , `\nobj3:${JSON.stringify(obj3)}`
)

10 Comments

this is possibly the correct answer, you need to split the keys into distinct objects,
This will fail if the objects have the same property name.
@FelixKling Can you describe what you mean?
If all objects had the property abc, not def, then your code would result in an array with a single object. Of course that might be the expected result, I don't know.
confusion, i think i rather don't do inmmutable here, just use push() to a new var.
|

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.