Reputation: 117
So I have a JavaScript function that gets an object and has a precreated object. The goal is that the function adds all missing properties of the passed object to the precreated one.
When just comparing one level, this is easy. For example in order to achieve this:
Precreated: {hello: "world"}
Passed: {hello: "there", colour: "green"}
Result: {hello: "world", colour: "green"}
You just look over each key of the passed object, look if that key already exists in the precreated one, and if not, add it with the respective value.
However, if you want to do this with multiple levels it kinda gets weird. For example, I want this to work:
Precreated: {hello: {there: true}}
Passed: {hello: {world: true}}
Result: {hello: {there: true, world: true}}
My idea was that I would just loop over the passed object, and if I find an object inside, call the function again with that object, and so on until all children were processed by the function.
When you do that, however, you would have to compare the children of both objects dynamically. Say, I know in the programme how many levels deep it is, what the key is called and so on, how do I programmatically access it?
I'm asking because I can't hardcode something like if (result[key1][key2][key3]...
, and something like if (result[keys.join(..)]...
isn't possible as well I think.
So how do I programmatically access a property of an object which is multiple levels deep, not knowing how deep at the time of writing the code?
Upvotes: 3
Views: 1279
Reputation: 1
You can use for..of
loop, Object.keys()
to check if property of passed object is an object, if true recursively call function with original object, passed object and key of passed object as parameters then assign property to original object, else check if property does not exist in original object, if true assign passed property to original object.
var precreated1 = {
hello: {
there: true
}
};
var precreated2 = {
hello: "world"
};
function addProps(props, obj, key) {
for (let prop of Object.keys(props)) {
if (Object.getPrototypeOf(props[prop]) === Object.prototype) {
addProps(props[prop], obj, prop)
} else {
if (key) {
obj[key][prop] = props[prop]
} else {
if (!(prop in obj)) {
obj[prop] = props[prop]
}
}
}
}
}
addProps({
hello: {
world: true
}
}, precreated1);
console.log("precreated1:", precreated1);
addProps({
hello: "there",
colour: "green"
}, precreated2);
console.log("precreated2:", precreated2);
Upvotes: 0
Reputation: 2342
This existing answer to a post mentioned by @4castle should be exactly what you want: https://stackoverflow.com/a/34749873/1406083
My idea was that I would just loop over the passed object, and if I find an object inside, call the function again with that object, and so on until all children were processed by the function.
You've already worked out that you want to use recursion, which is great. JavaScript allows you to reflect on the keys of an object with a for ... in
loop. You just need to make sure that the object you want to copy is indeed an object and not just a value.
The answer I linked uses their own isObject
for this. Object filling is done recursively with Object.assign
Upvotes: 1