Skip to content

Commit

Permalink
Allow for differents keys and values in objects to merge. Fixes #828.
Browse files Browse the repository at this point in the history
Add tests.
  • Loading branch information
ivmartel committed Jan 14, 2021
1 parent cc92f36 commit a052b7a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 35 deletions.
83 changes: 48 additions & 35 deletions src/utils/operator.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,52 +121,65 @@ dwv.utils.mergeObjects = function (obj1, obj2, idKey, valueKey) {
res[idKey] = {value: [id1, id2], merged: true};
}

// loop through object1
// get keys
var keys1 = Object.keys(obj1);
for (var i = 0, leni = keys1.length; i < leni; ++i) {
var key1 = keys1[i];
if (key1 !== idKey) {
var value1 = obj1[key1];
// default result
var value = value1;
if (!Object.prototype.hasOwnProperty.call(value1, valueKey)) {
throw new Error('Value not found in first object while merging: ' +
valueKey + ', value: ' + value1);
// keys2 without duplicates of keys1
var keys2 = Object.keys(obj2).filter(function (item) {
return keys1.indexOf(item) < 0;
});
var keys = keys1.concat(keys2);

// loop through keys
for (var i = 0, leni = keys.length; i < leni; ++i) {
var key = keys[i];
if (key !== idKey) {
// first
var subValue1 = null;
if (Object.prototype.hasOwnProperty.call(obj1, key)) {
var value1 = obj1[key];
if (Object.prototype.hasOwnProperty.call(value1, valueKey)) {
subValue1 = value1[valueKey];
}
}
var subValue1 = value1[valueKey];
if (Object.prototype.hasOwnProperty.call(obj2, key1)) {
var value2 = obj2[key1];
if (!Object.prototype.hasOwnProperty.call(value2, valueKey)) {
throw new Error('Value not found in second object while merging: ' +
valueKey + ', value: ' + value2);
// second
var subValue2 = null;
if (Object.prototype.hasOwnProperty.call(obj2, key)) {
var value2 = obj2[key];
if (Object.prototype.hasOwnProperty.call(value2, valueKey)) {
subValue2 = value2[valueKey];
}
var subValue2 = value2[valueKey];
// create merge object if different values
if (subValue2 !== subValue1) {
// add to merged object or create new
if (mergedObj1) {
}
// result value
var value;
// create merge object if different values
if (subValue2 !== subValue1) {
value = {};
// add to merged object or create new
if (mergedObj1) {
if (dwv.utils.isObject(subValue1)) {
value[valueKey] = subValue1;
} else {
// merged object with repeated value
// copy it with the index list
if (!dwv.utils.isObject(subValue1)) {
value[valueKey] = {};
for (var j = 0; j < id1.length; j++) {
value[valueKey][id1[j]] = subValue1;
}
value[valueKey] = {};
for (var j = 0; j < id1.length; j++) {
value[valueKey][id1[j]] = subValue1;
}
value[valueKey][id2] = subValue2;
} else {
// create merge object
var newValue = {};
newValue[id1] = subValue1;
newValue[id2] = subValue2;
value[valueKey] = newValue;
}
// add obj2 value
value[valueKey][id2] = subValue2;
} else {
// create merge object
var newValue = {};
newValue[id1] = subValue1;
newValue[id2] = subValue2;
value[valueKey] = newValue;
}
} else {
throw new Error('Cannot find key1 in second object while merging.');
value = value1;
}
// store value in result object
res[key1] = value;
res[key] = value;
}
}
return res;
Expand Down
57 changes: 57 additions & 0 deletions tests/utils/operator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,61 @@ QUnit.test('Test merge objects.', function (assert) {
JSON.stringify(res03),
JSON.stringify(ref03),
'merge objects 03');

// test #10: missing key in first object
var obj101 = {id: {value: 0}, a: {value: 1}};
var obj102 = {id: {value: 1}, a: {value: 2}, b: {value: 1}};
var ref10 = {
id: {value: [0, 1], merged: true},
a: {value: {0: 1, 1: 2}},
b: {value: {0: null, 1: 1}}
};
var res10 = dwv.utils.mergeObjects(obj101, obj102, 'id', 'value');
assert.equal(
JSON.stringify(res10),
JSON.stringify(ref10),
'merge objects 10');

// test #10: missing key in second object
var obj111 = {id: {value: 0}, a: {value: 1}, b: {value: 1}};
var obj112 = {id: {value: 1}, a: {value: 2}};
var ref11 = {
id: {value: [0, 1], merged: true},
a: {value: {0: 1, 1: 2}},
b: {value: {0: 1, 1: null}}
};
var res11 = dwv.utils.mergeObjects(obj111, obj112, 'id', 'value');
assert.equal(
JSON.stringify(res11),
JSON.stringify(ref11),
'merge objects 11');

// test #12: missing value in first object
var obj121 = {id: {value: 0}, a: {value: 1}, b: {}};
var obj122 = {id: {value: 1}, a: {value: 2}, b: {value: 1}};
var ref12 = {
id: {value: [0, 1], merged: true},
a: {value: {0: 1, 1: 2}},
b: {value: {0: null, 1: 1}}
};
var res12 = dwv.utils.mergeObjects(obj121, obj122, 'id', 'value');
assert.equal(
JSON.stringify(res12),
JSON.stringify(ref12),
'merge objects 12');

// test #13: missing value in second object
var obj131 = {id: {value: 0}, a: {value: 1}, b: {value: 1}};
var obj132 = {id: {value: 1}, a: {value: 2}, b: {}};
var ref13 = {
id: {value: [0, 1], merged: true},
a: {value: {0: 1, 1: 2}},
b: {value: {0: 1, 1: null}}
};
var res13 = dwv.utils.mergeObjects(obj131, obj132, 'id', 'value');
assert.equal(
JSON.stringify(res13),
JSON.stringify(ref13),
'merge objects 13');

});

0 comments on commit a052b7a

Please sign in to comment.