我有两个对象,我想列出两者之间的变化,如下所述:
目前我正在关注输出
当前值 || 新价值
标题:对象1 || 标题:对象1已更新
description :对象1说明 || description :对象1说明已更新
目前我的代码适用于根级别比较(如上所述)。但我正在寻找深度/嵌套子级别差异的比较。
我的输出应如下所示
当前值 || 新价值
标题:对象1 || 标题:对象1已更新
description :对象1说明 || description :对象1说明已更新
releations.tools [0] .title :我的第一个工具 || releations.tools [0] .title :我的第一个工具UPDATED
relations.tools [0] .types [1] .name :test2 || DELETED
relations.training [0] .description :培训说明 || relations.training [0] .description :培训说明更新了
relations.training [0] .trainingTypes [1] .name :in-person || DELETED
我当前的代码
function diffObjects(obj1, obj2) {
let res = [];
let objKeysArray = _.keys(obj2) || [];
if (!obj1 || !obj2) {
return res;
}
if (objKeysArray.length === 0) {
return res;
}
_(objKeysArray).forEach((key) => {
console.log(obj1[key], obj2[key]);
if (_.isArray(obj1[key]) && _.isArray(obj2[key])) {
} else if (_.isObject(obj1[key]) && _.isObject(obj2[key])) {
} else if (!_.isEqual(obj1[key], obj2[key])) {
let change1 = `${key} : ${obj1[key]}`;
let change2 = `${key} : ${obj2[key]}`;
res.push({
currentVal: change1,
newVal: change2
});
}
});
return _.flattenDeep(res);
}
我在这里为上面的代码创建了一个小提琴: JSFiddle链接:https://jsfiddle.net/vr0pgemj/
我已经引用了这些帖子:
Deep comparison of objects/arrays
Javascript Deep Comparison
但他们只给我TRUE或FALSE结果而不是我想要的差异。
答案 0 :(得分:0)
我使用ECMAscript6语法为你的小提琴here做了一个工作分叉。
以下是嵌入式版本:
(function() {
'use strict';
function diffObj(obj1, obj2, ref) {
var prefix = ref || '';
var res = [];
if (!_.isUndefined(obj1) && _.isUndefined(obj2)) {
res.push({
currentVal: prefix + ' : ' + JSON.stringify(obj1),
newVal: 'DELETED'
});
} else if (_.isUndefined(obj1) && !_.isUndefined(obj2)) {
res.push({
currentVal: 'DELETED',
newVal: prefix + ' : ' + JSON.stringify(obj2)
});
}
if (_.isUndefined(obj1) || _.isUndefined(obj2)) {
return _.flattenDeep(res);
}
var keys = _.uniq(_.keys(obj1).concat(_.keys(obj2)));
_(keys).forEach(function(key) {
var value1 = obj1[key];
var value2 = obj2[key];
if (!_.isUndefined(value1) && _.isUndefined(value2)) {
res.push({
currentVal: prefix + key + ' : ' + value1,
newVal: 'DELETED'
});
} else if (_.isUndefined(value1) && !_.isUndefined(value2)) {
res.push({
currentVal: 'DELETED',
newVal: prefix + key + ' : ' + value2
});
} else if (_.isArray(value1) && _.isArray(value2)) {
var entries = Math.max(value1.length, value2.length);
for (var i = 0; i < entries; i++) {
res.push(diffObj(value1[i], value2[i], prefix + key + '[' + i + '].'));
}
} else if (_.isObject(value1) && _.isObject(value2)) {
res.push(diffObj(value1, value2, prefix + key + '.'));
} else if (!_.isEqual(value1, value2)) {
res.push({
currentVal: prefix + key + ' : ' + value1,
newVal: prefix + key + ' : ' + value2
});
}
});
return _.flattenDeep(res);
}
var json1 = {
"id": 1,
"title": "Object 1",
"description": "Object 1 Description",
"test": "foo bar",
"relations": {
"tools": [{
"id": 2,
"title": "my first tool",
"description": "tools description",
"types": [{
"id": 123,
"name": "test"
}, {
"id": 111,
"name": "test2"
}]
}],
"training": [{
"id": 3,
"title": "Test training",
"description": "training Description",
"trainingTypes": [{
"id": 1,
"name": "online"
}, {
"id": 2,
"name": "in-person"
}, {
"id": 3,
"name": "boot camp"
}]
}]
}
};
var json2 = {
"id": 1,
"title": "Object 1 UPDATED",
"description": "Object 1 Description UPDATED",
"relations": {
"tools": [{
"id": 2,
"title": "my first tool UPDATED",
"description": "tools description",
"types": [{
"id": 123,
"name": "test"
}]
}],
"training": [{
"id": 3,
"title": "Test training",
"description": "training Description UPDATED",
"trainingTypes": [{
"id": 1,
"name": "online"
}, {
"id": 3,
"name": "boot camp"
}]
}]
}
};
var res = diffObj(json1, json2);
res = res.map(function(d) {
return '<tr><td>' + d.currentVal + '</td><td>' + d.newVal + '</td></tr>';
});
$('#tableResult > tbody').append(res);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<table id="tableResult" class="table table-hover table-striped">
<thead>
<tr>
<th>
current
</th>
<th>
new
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>