目前还有些限制,比如连续嵌套数组的情况,有办法解决的欢迎指点一下
const obj1 = [{ a: 1 }, { a: 1, b: 2 }, { a: 2 }];
const obj2 = [{ a: 1 }, { a: 2 }, { a: 1, b: 2, c: 3 }];
var result = this.checkArrayInArray(obj1, obj2);
console.log(result);
checkArrayInArray(a, b) {
if (a.length > b.length) {
return false;
}
return this.checkArrInArr(a, b);
},
checkArrInArr(a, b) {
var bool;
for (var i = 0; i < a.length; ++i) {
if (a[i] instanceof Array) {
bool = this.checkArrInArr(a[i], b);
if (!bool) return false;
}
else if (a[i] instanceof Object) {
bool = this.checkObjInArr(a[i], b);
if (!bool) return false;
}
else {
bool = this.checkBasicInArr(a[i], b);
if (!bool) return false;
}
}
return true;
},
checkObjInArr(a, b) {
for (var i = 0; i < b.length; ++i) {
var bool = this.checkObjInObj(a, b[i]);
if (bool) return true;
}
return false;
},
checkObjInObj(a, b) {
var n = 0;
for (var i in a) {
if (a[i] instanceof Array) {
if (b instanceof Array) {
return this.checkArrInArr(a[i], b);
}else{
return false;
}
} else if (a[i] instanceof Object) {
if(b instanceof Object){
return this.checkObjInObj(a[i], b);
}else{
return false;
}
} else {
if (b.hasOwnProperty(i) && a[i] == b[i]) {
n++;
}
}
}
if (n == Object.keys(a).length) {
return true;
}
return false;
},
checkBasicInArr(a, b) {
return b.includes(a);
},
同事的2.0版本
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; // 如果flag变为false说明数据存在差异应跳出循环
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 = [];
const 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) {
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循环添加label便于在内部终止循环
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;
}
}
//设定json--准备调用
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), '???');