```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); ```