```javascript
const updateObj = (d1, d2) => {
const stack = [[d1, d2]];
while (stack.length > 0) {
const [currentD1, currentD2] = stack.pop();
for (const key in currentD2) {
if (!currentD1.hasOwnProperty(key) || typeof currentD2[key] !== typeof currentD1[key]) {
continue;
}
if (typeof currentD2[key] === 'object' && typeof currentD1[key] === 'object') {
stack.push([currentD1[key], currentD2[key]]);
} else {
currentD1[key] = currentD2[key];
}
}
}
}
// Example usage
const d1 = { a: undefined, b: { x: 10, y: 20, zdict: { a: 'a', b: 'b' } }, c: 3 };
const d2 = { b: { y: 200, z: 30, yy: 100}, c: {a: {a: 100, b: 200, c: 300}}, d: 5, z: 999, a: 100, aa: undefined};
updateObj(d1, d2);
console.log(d1);
```
```python
def update_dict_iteratively(d1, d2):
stack = [(d1, d2)]
while stack:
current_d1, current_d2 = stack.pop()
for key, value in current_d2.items():
if key not in current_d1 or type(d1) != type(d2):
continue
if isinstance(value, dict) and isinstance(current_d1[key], dict):
stack.append((current_d1[key], value))
else:
current_d1[key] = value
# Example usage
d1 = {"a": 1, "b": {"x": 10, "y": 20, "zdict": {"a": "a", "b": "b"}}, "c": 3}
d2 = {"b": {"y": 21, "z": 30, "yy": 100}, "c": 4, "d": 5, "z": 999}
update_dict_iteratively(d1, d2)
print(d1)
```
# other implementations
```javascript
// /Users/hause/Dropbox/projects/scratch_js/unpack.js
// default values
let chatParams = {
model: { model: "gpt4", key: undefined, abc: false },
appearance: { color: 'red', size: 10000 },
study: { subject: 'math', grade: 999, abc: 'abc' }
};
// from qualtrics
let chatParamsQualtrics = {
model: { model: "9", key: "sk-1234" },
appearance: { color: '99' },
study: { subject: '999' },
someWeirdStuff: { abc: 9999 }
};
console.log("chatParams (pre)", chatParams)
console.log("chatParamsQualtrics (pre)", chatParamsQualtrics)
// update accordingly
for (let k1 in chatParamsQualtrics) {
if (k1 in chatParams) {
const kQualtrics = chatParamsQualtrics[k1];
const kDefault = chatParams[k1]
for (let k2 in kQualtrics) {
if (k2 in kDefault) {
chatParams[k1][k2] = kQualtrics[k2]
}
}
}
}
console.log("chatParams (post)", chatParams)
console.log("chatParamsQualtrics (post)", chatParamsQualtrics)
```
```javascript
// deep recursive merge
// merges even keys non-existent keys
function mergeDeep(target, source) {
for (const key in source) {
if (source[key] instanceof Object && key in target) {
Object.assign(source[key], mergeDeep(target[key], source[key]));
}
}
Object.assign(target || {}, source);
return target;
}
// recursive merge
// only merges existing keys
function mergeDeep2(target, source) {
for (const key in source) {
if (key in target) {
if (source[key] instanceof Object && target[key] instanceof Object) {
mergeDeep2(target[key], source[key]);
} else {
target[key] = source[key];
}
}
}
return target;
}
let chatParams = {
model: { model: "gpt4", key: undefined, abc: false },
appearance: { color: 'red', size: 10000 },
study: { subject: 'math', grade: 999, abc: 'abc' }
};
console.log(chatParams);
let chatParamsQualtrics = {
model: { model: "9", key: "sk-1234" },
appearance: { color: '99' },
study: { subject: '999' },
someWeirdStuff: { abc: 9999 }
};
chatParams = mergeDeep2(chatParams, chatParamsQualtrics);
console.log(chatParams);
```