const dataType = (data) = > {
const type = Object.prototype.toString.call(data);
const startIndex = type.indexOf(' ') + 1;
return type.slice(startIndex, -1);
};
const jsonContrast = (obj1, obj2) = > {
let flag = true;
function compare(obj1, obj2) {
// Array case
const oldType = dataType(obj1);
const newType = dataType(obj2);
if(oldType ! == newType) { flag =false;
} else if (oldType === 'Object') { // The object type determines whether the attribute exists
flag = objectCompare(obj1, obj2);
} else if (oldType === 'Array') {
flag = arrayCompare(obj1, obj2);
}
if (flag === false) {
return false;
} else {
return true; }}return compare(obj1, obj2);
};
// Object comparison
function objectCompare(obj1, obj2) {
let flag = true;
for (let [k, v] of Object.entries(obj1)) { The // method returns an array of key-value pairs for the given object's own enumerable properties
if(! flag)break; // If flag changes to false, data differences should be broken out of the loop
if (obj2.hasOwnProperty(k)) { // Attribute exists, check the type
if (dataType(v) === dataType(obj2[k]) && (dataType(v) === 'Object' || dataType(v) === 'Array')) { // Object type
flag = jsonContrast(v, obj2[k]);
} else if(dataType(v) ! == dataType(obj2[k])) {// Other types
flag = false; }}else {
flag = false; }}if (flag === false) {
return false;
} else {
return true; }}// Array comparison
function arrayCompare(obj1, obj2) {
let flag = true;
let arrFlag = true;
let objFlag = true;
const obj1_statistics = {
String: 0.Number: 0.Boolean: 0.Array: 0.Object: 0
};
const obj2_statistics = {
String: 0.Number: 0.Boolean: 0.Array: 0.Object: 0
};
const tag = ['String'.'Number'.'Boolean'.'Array'.'Object'];
const obj1_data_arr = [];
const obj2_data_arr = [];
let obj1_data_obj = [];
const obj2_data_obj = [];
// Array comparison first compares the length
if (obj1.length > obj2.length) {
flag = false;
} else {
// Because there are multiple types of the same type in the array, and the order can be not fixed, we need to count the uniform data type of the pull data separately
// If the data is of complex type, it needs to be done and stored for comparison. There may be more complex types of new data than old data. There may also be cases where the contents of two objects are the same, and the sequence of data is inconsistent, etc., which need to be processed separately
for (let i in obj1) {
const type = dataType(obj1[i]);
++obj1_statistics[type];
if (type === 'Array') {
obj1_data_arr.push(obj1[i]);
}
if (type === 'Object') { obj1_data_obj.push(obj1[i]); }}for (let i in obj2) {
const type = dataType(obj2[i]);
++obj2_statistics[type];
if (type === 'Array') {
obj2_data_arr.push(obj2[i]);
}
if (type === 'Object') { obj2_data_obj.push(obj2[i]); }}// If the new data is less than the old data, it indicates that the data is different
const statistics_result = tag.findIndex(t= > obj1_statistics[t] > obj2_statistics[t]);
if (statistics_result === -1) {
obj1_data_obj = obj1_data_obj.sort((a, b) = > Object.keys(b).length - Object.keys(a).length); // To sort old data objects, the more key values, the higher the priority comparison
arrFlag = children(obj1_data_arr, obj2_data_arr);
objFlag = children(obj1_data_obj, obj2_data_obj);
} else {
flag = false; }}if(! arrFlag || ! objFlag) { flag =false;
}
if (flag === false) {
return false;
} else {
return true; }}function children(obj1_data, obj2_data) {
let flag = true;
let chelidFlag = true;
outside: for (let i = 0; i < obj1_data.length; i++) { // Add a label to the for loop to make it easier to terminate the loop internally
for (let j = 0; j < obj2_data.length; j++) {
if (dataType(obj1_data[i]) === dataType(obj2_data[j]) && (dataType(obj1_data[i]) === 'Array' || dataType(obj1_data[i]) === 'Object')) {
flag = jsonContrast(obj1_data[i], obj2_data[j]);
if (flag === true) {
if(obj1_data.length ! == i) { obj1_data.splice(i,1);
obj2_data.splice(j, 1);
chelidFlag = children(obj1_data, obj2_data);
if (chelidFlag === false) {
breakoutside; }}breakoutside; }}}}if (flag === false || chelidFlag === false) {
return false;
} else {
return true; }}// Set json-- ready to call
var jsonA = {
"a": { b: 2 },
"d": [1[[], {a: 1.b: [{ d: [{ e: [{}, []]}]}, {a: 1.b: 2 }, { a: [{ b: 1}},1]]};var jsonB = {
"a": { b: 2 },
"d": [1[{a: [{ b: 1{}}], [],a: 1.b: [{ d: [{ e: [[], {}]}]}, {d: 1 }, { a: 1.b: 1 }, 1]]};console.log(jsonContrast(jsonA, jsonB), '????? ');
Copy the code