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) {
const oldType = dataType(obj1);
const newType = dataType(obj2);
if (oldType !== newType) {
flag = false;
} else if (oldType === 'Object') {
flag = objectCompare(obj1, obj2);
} else if (oldType === 'Array') {
flag = arrayCompare(obj1, obj2);
}
if (flag === false) {
return false;
} else {
return true;
}
}
return compare(obj1, obj2);
};
function objectCompare(obj1, obj2) {
let flag = true;
for (let [k, v] of Object.entries(obj1)) {
if (!flag) break;
if (obj2.hasOwnProperty(k)) {
if (dataType(v) === dataType(obj2[k]) && (dataType(v) === 'Object' || dataType(v) === 'Array')) {
flag = jsonContrast(v, obj2[k]);
} else if (dataType(v) !== dataType(obj2[k])) {
flag = false;
}
} else {
flag = false;
}
}
if (flag === false) {
return false;
} else {
return true;
}
}
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 = [];
if (obj1.length > obj2.length) {
flag = false;
} else {
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]);
}
}
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);
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++) {
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) {
break outside;
}
}
break outside;
}
}
}
}
if (flag === false || chelidFlag === false) {
return false;
} else {
return true;
}
}
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), '???');