I'm trying to write a function that will let me update my kitchen
in this example below. Using something like underscore's extend
, however, blows away the beer in my fridge as it's updating the entire fridge
object.
Is there a simple method I can use so that I only make updates with the properties that change in my changeKitchen
object and not update the entire fridge
object?
// My original kitchen
var kitchen = {
fridge: {
beer: true,
celery: false
},
cabinets: {
candy: true
}
};
// updates I would like to make to my kitchen
var changeKitchen = {
fridge: {
celery: true
}
};
var updatedKitchen = _.extend(kitchen, changeKitchen);
console.log(updatedKitchen);
Returns
var kitchen = {
fridge: {
celery: false // beer is gone
},
cabinets: {
candy: true
}
};
However I would like to have:
var kitchen = {
fridge: {
beer: true,
celery: true // changed
},
cabinets: {
candy: true
}
};
Since you're already using Underscore, you could use Lodash instead, which is a superset of Underscore, and use its #merge
function.
See this question about Differences between Lodash and underscore
// My original kitchen
var kitchen = {
fridge: {
beer: true,
celery: false
},
cabinets: {
candy: true
}
};
// updates I would like to make to my kitchen
var changeKitchen = {
fridge: {
celery: true
}
};
var updatedKitchen = _.merge(kitchen, changeKitchen);
document.write(JSON.stringify(updatedKitchen));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
Use _.extend
on the nested objects instead:
function update(obj1, obj2) {
for (var p in obj2) {
if (obj1[p]) {
_.extend(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
}
}
update(kitchen, changeKitchen);
DEMO
Here is a solution in plain Javascript:
var kitchen = { fridge: { beer: true, celery: false }, cabinets: { candy: true } },
changeKitchen = { fridge: { celery: true } };
function update(source, target) {
Object.keys(target).forEach(function (k) {
if (typeof target[k] === 'object') {
source[k] = source[k] || {};
update(source[k], target[k]);
} else {
source[k] = target[k];
}
});
}
update(kitchen, changeKitchen);
document.write('<pre>' + JSON.stringify(kitchen, 0, 4) + '</pre>');
Try using for..in
loop , Object.keys()
// My original kitchen
var kitchen = {
fridge: {
beer: true,
celery: false
},
cabinets: {
candy: true
}
};
var changeKitchen = {
fridge: {
celery: true
}
};
for (var prop in changeKitchen) {
if (kitchen[prop]) {
kitchen[prop]
[Object.keys(changeKitchen[prop])] = changeKitchen[prop]
[Object.keys(changeKitchen[prop])]
}
}
console.log(kitchen)