我有一个程序,可以对提供给它的2个对象进行深度比较,并使用递归进行。我的问题是,由于我使用全局变量来保留信息,因此必须在每次对该函数进行任何后续调用之前都将其重置。除了使用全局变量之外,是否还有其他方法可以维护变量值,并且它不是那么麻烦?
Xaml
答案 0 :(得分:2)
您根本不需要使用它:您可以通过递归来完成整个操作:
time col1 col2 col3
2018-04-29 02:12:00 1 50 3
2018-04-30 01:58:00 1 40 3
2018-05-01 23:34:00 1 11 3
2018-04-29 02:02:00 2 10 4
2018-05-01 05:48:00 2 25 4
答案 1 :(得分:0)
我创建了一个实用程序,用于深入比较两个对象。它对两个对象使用递归调用,并返回true或false。
Github回购链接-https://github.com/maninder-singh/deep-compare
DOCKET
JS
<script src="deep-compare.js"></script>
答案 2 :(得分:0)
您可以使用我的各种JS库提供的经过测试的防弹对象相等方法来执行对象相等测试,如下所示
lodash
库:
_.isEqual(obj1, obj2)
或
自定义测试方法
function deepCompare () {
var i, l, leftChain, rightChain;
function compare2Objects (x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof (x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects (x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
答案 3 :(得分:0)
function deepEqual(object1, object2) {
//check if the given objects have the same datatype
if (typeof(object1) === typeof(object2)) {
//check if the given object is a primitive datatype and how to handle null values
if ((typeof(object1) !== 'object') && (typeof(object2) !== 'object') ||
object1 === null || object2 === null) {
return object1 === object2;
} else {
//if they are both objects
if (object1 !== null && object2 !== null) {
let object1Keys = Object.keys(object1);
let object2Keys = Object.keys(object2);
//check if the arrays have the same length
if (object1Keys.length === object2Keys.length) {
let isEqual;
for (let index = 0; index < object1Keys.length; index++) {
//make sure both key:value pairs match
if (object1Keys[index] === object2Keys[index]) {
//check if the current value is another object
if (typeof(object1[object1Keys[index]]) === 'object' &&
typeof(object2[object2Keys[index]]) === 'object') {
return deepEqual(object1[object1Keys[index]], object2[object2Keys[index]]);
} else {
isEqual = (object1[object1Keys[index]] === object2[object2Keys[index]]);
}
} else {
return false; //return false if keys dont match
}
}
return isEqual;
} else {
return false; //return false if 2 arrays dont have the same length
}
}
}
} else {
return false; //return false if 2 object types dont match
}
}
let obj1 = {
a: 'somestring',
b: 42,
c: {
1: 'one',
2: {
3: 'Three'
}
}
};
let obj2 = {
a: 'somestring',
b: 42,
e: {
1: 'one',
2: {
3: 'Three'
}
}
};
console.log("obj1 == obj2 : ");
console.log(deepEqual(obj1, obj2));
let obj3 = {
a: 'somestring',
b: 42,
c: {
1: 'one',
2: {
4: 'Three'
}
}
};
let obj4 = {
a: 'somestring',
b: 42,
c: {
1: 'one',
2: {
3: 'Three'
}
}
};
console.log("obj3 == obj4 : ");
console.log(deepEqual(obj3, obj4));
let obj = {
name: {
gender: "F"
},
age: 20
};
console.log(deepEqual(obj, {
name: {
gender: "F"
},
age: 20
}));
console.log('null == obj3');
console.log(deepEqual(null, obj3));
console.log('5 == obj3');
console.log(deepEqual(5, obj3));
console.log('null == null');
console.log(deepEqual(null, null));
console.log('10 == 5');
console.log(deepEqual(10, 5));
console.log(`10 == '10'`);
console.log(deepEqual(10, '10'));
老实说,我更喜欢@Andrew Ridgway的解决方案。它非常简单而优雅。
但是,我确实清理了我正在使用的函数,以避免使用全局变量。
这是解决同一问题的另一种方法,尽管有点复杂。
我愿意接受进一步的建议。谢谢!