Reputation: 599
I am experimenting on objects, and what I am trying to achieve is to remove keys found in object1
if those keys exist in object2
.
Here is the example:
var original = {
a: 1,
b: 2,
c: 3,
e: {
tester: 0,
combination: {
0: 1
}
},
0: {
test: "0",
2: "hello"
}
};
var badKeys = {
a: 1,
b: 2,
0: {
test: "0",
}
}
var expectedResult = {
c: 3,
e: {
tester: 0,
combination: {
0: 1
}
},
0: {
2: "hello"
}
}
I've tried using underscore
difference function, but it doesn't work for objects, also not sure if this is the right function.
Can you help me to get the var expectedResult
right?
Upvotes: 2
Views: 991
Reputation: 369
Truly a job for some recursion and a bit of functional programming using a pure function. (Tested with Node v7.7.1)
"DoForAllNestedObjects" for applying some function "whattodo" on "every leaf on the dictionary tree" when there is an corresponding "leaf" in baddict.
let DoForAllNestedValues = (dict, baddict, whattodo) => {
for (let key in dict) {
if (typeof (dict[key]) === 'object' && typeof (baddict[key]) === 'object')
DoForAllNestedValues(dict[key], baddict[key], whattodo);
else
if (baddict[key])
whattodo(dict, key);
}
}
DoForAllNestedValues(original, badKeys, (obj, val) => delete obj[val]);
console.log(original);
Upvotes: 0
Reputation: 122047
You can create recursive function that will return new object using for...in
loop.
var original = {"0":{"2":"hello","test":"0"},"a":1,"b":2,"c":3,"e":{"tester":0,"combination":{"0":1}}}
var badKeys = {"0":{"test":"0"},"a":1,"b":2}
function remove(o1, o2) {
var result = {}
for (var i in o1) {
if (!o2[i]) result[i] = o1[i]
else if (o2[i]) {
if (typeof o1[i] == 'object' && typeof o2[i] == 'object') {
result[i] = Object.assign(result[i] || {}, remove(o1[i], o2[i]))
} else if (o1[i] != o2[i]) result[i] = o1[i]
}
}
return result
}
console.log(remove(original, badKeys))
Upvotes: 0
Reputation: 386604
You could use an iterative and recursive approach for geeting the wanted properties in a new object.
function deleteKeys(good, bad, result) {
Object.keys(good).forEach(function (key) {
if (bad[key] && typeof bad[key] === 'object') {
result[key] = {};
deleteKeys(good[key], bad[key], result[key]);
return;
}
if (!(key in bad) || good[key] !== bad[key]) {
result[key] = good[key];
}
});
}
var original = { a: 1, b: 2, c: 3, e: { tester: 0, combination: { 0: 1 } }, 0: { test: "0", 2: "hello", another: { a: { B: 2, C: { a: 3 } }, b: 2 } } },
badKeys = { a: 1, b: 2, 0: { test: "0", random: 2, another: { a: 1 } } },
result = {};
deleteKeys(original, badKeys, result);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 1248
This would be the algorithm:
function removeDifferences (original, removeKeys) {
// Get keys of to be deleted properties.
var keys = Object.keys(removeKeys);
// Iterate all properties on removeKeys.
for (key of keys) {
// Check if property exists on original.
if (typeof original[key] !== undefined) {
// If the property is an object, call same function to remove properties.
if (typeof removeKeys[key] === 'object') {
removeDifferences(original[key], removeKeys[key]);
} else {
delete original[key];
}
}
}
return original;
}
Applied to your case:
/* Your data. */
var original = {
a: 1,
b: 2,
c: 3,
e: {
tester: 0,
combination: {
0: 1
}
},
0: {
test: "0",
2: "hello"
}
};
var badKeys = {
a: 1,
b: 2,
0: {
test: "0",
}
};
var expectedResult = {
c: 3,
e: {
tester: 0,
combination: {
0: 1
}
},
0: {
2: "hello"
}
};
/* Function */
function removeDifferences(original, removeKeys) {
// Get keys of to be deleted properties.
var keys = Object.keys(removeKeys);
// Iterate all properties on removeKeys.
for (key of keys) {
// Check if property exists on original.
if (typeof original[key] !== undefined) {
// If the property is an object, call same function to remove properties.
if (typeof removeKeys[key] === 'object') {
removeDifferences(original[key], removeKeys[key]);
} else {
delete original[key];
}
}
}
return original;
}
/* Application */
var output = removeDifferences(original, badKeys);
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0