Reputation: 1667
Here is my fiddle : DEMO
By recursive iterations, I am able to find the key in object2 object3 and replace its value by the values from data2 data3 objects.
However, I am unable to replace the value if it is an array. (key called 'coordinates' in this case) How could this be fixed?
function update(object, data) {
function getAllKeys(o) {
Object.keys(o).forEach(function(k) {
if (typeof o[k] === 'object') {
return getAllKeys(o[k]);
}
keys[k] = o;
});
}
var keys = Object.create(null);
getAllKeys(object);
Object.keys(data).forEach(function(k) {
if (keys[k] && k in keys[k]) { // check if key for update exist
keys[k][k] = data[k];
}
});
}
Upvotes: 1
Views: 2992
Reputation: 13014
Update the getAllKeys
method with:
function getAllKeys(o) {
Object.keys(o).forEach(function(k) {
contains_object = Array.isArray(o[k]) && o[k].some(val=> { return typeof val == "object" && !Array.isArray(val); });
if ((Array.isArray(o[k]) && !contains_object) || typeof o[k] !== 'object') {
keys[k] = o;
} else {
return getAllKeys(o[k]);
}
keys[k] = o;
});
}
Note: !(o[k] instanceof Array)
- http://jsfiddle.net/08pnu7rx/1/
Upvotes: 2
Reputation: 281626
The problem in your code is that typeof o[k] === 'object'
returns true even it o[k] is an array which is the case for coordinated, You need a negative check for array too like
Object.keys(o).forEach(function(k) {
if (typeof o[k] === 'object'&& !Array.isArray(o[k])) {
return getAllKeys(o[k]);
}
keys[k] = o;
});
According to the docs or typeof:
// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === 'object';
Upvotes: 0
Reputation: 8605
The problem is that typeof
also returns object
for arrays.
You want to change your function to still assign the key when the object is an array.
function getAllKeys(o) {
Object.keys(o).forEach(function(k) {
if (Array.isArray(o[k]) || typeof o[k] !== 'object') {
keys[k] = o;
} else {
return getAllKeys(o[k]);
}
});
}
Notice I swapped around the logic, so you first check for either an array or another non-object type. If that check passes, you assign the value. If not, you recurse.
You should note that this is not at all specific to arrays. You will have similar problems if you have a nested property that is a Date
, for example.
Upvotes: 0