2016-09-21 2 views
0

У меня есть этот объектКак мутировать объект без дублирования?

var originalObj = { 
    shop: [ 
    { id: 1, list: "buy milk", complete: false}, 
    { id: 2, list: "buy bread", complete: false} 
    ] 
} 

Я хотел бы изменить первый элемент в complete: true

var newObj = Object.assign({}, originalObj, { 
    ['shop']: [ 
    {...originalObj['shop'][0] 
     complete: true}, ...originalObj['shop'] 
    ] 
}) 

Проблема с этим состоит в том, что newObj заканчивает с тремя объектами, где один я пытаюсь для редактирования дублируется.

+0

Есть ли еще более важная проблема, чем кажется на первый взгляд? Почему не просто 'originalObj.shop [0] .complete = true'? –

+0

@JamesThorpe, но я не хочу менять исходный объект – relidon

+0

Это потому, что вы добавляете весь массив магазина обратно после добавления этого объекта {... originalObj.shop [0], complete: true} – inoabrian

ответ

1

Deep копия может иметь проблемы когда-то. Object.assign() копирует ссылку свойства, когда назначаемое свойство является объектом. Лучше вы можете использовать следующий метод.

var originalObj = { 
    shop: [ 
    { id: 1, list: "buy milk", complete: false}, 
    { id: 2, list: "buy bread", complete: false} 
    ] 
}; 
var newObj = JSON.parse(JSON.stringify(originalObj)); 
newObj.shop[0].complete = true; 
0

Мой комментарий: «Это потому, что вы добавляете весь массив магазин обратно, после того, как вы добавите этот объект {... originalObj.shop [0], полная: истинный}»

и ... originalObj.shop распространяет весь массив. поэтому у вас есть этот

[{the newly edited object with complete = true}, ...originalObj.shop] 
...originalObj.shop looks like this : 
[{ id: 1, list: "buy milk", complete: false}, 
{ id: 2, list: "buy bread", complete: false}] 

В моем ответе я фильтр "старый" {ID: 1, список: "купить молоко", полное: ложное} вне.

var changeObject = function(index, objectToEdit){ 
 
    var newObject = {}; 
 
    newObject = Object.assign({}, originalObj.shop[index]); 
 
    newObject.complete = true; 
 
    return newObject; 
 
}; 
 

 
var originalObj = { 
 
    shop: [ 
 
    { id: 1, list: "buy milk", complete: false}, 
 
    { id: 2, list: "buy bread", complete: false} 
 
    ] 
 
}; 
 

 
var changedObj = changeObject(0, originalObj); 
 
var unchangedObjs = originalObj.shop.filter(sobj => { 
 
    if(sobj.id != changedObj.id) 
 
    return sobj; 
 
}); 
 

 
var newObj = { 
 
    'shop': [ 
 
    changedObj, 
 
    ...unchangedObjs 
 
    ] 
 
}; 
 

 
console.log(JSON.stringify(newObj));

Просто заметил, что мой ответ полностью исключает решение, которое вы хотели. Так вот решение, которое вы хотите:

var newObj = { 
    'shop': [ 
    {...originalObj.shop[0], complete:true}, 
    ...originalObj.shop.filter(so => {return so.id != originalObj.shop[0].id}) 
    ] 
}; 
Смежные вопросы