Javascript 如何在没有顺序的情况下比较两个具有相同属性的 JSON?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26049303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:15:04  来源:igfitidea点击:

How to compare two JSON have the same properties without order?

javascriptjqueryjson

提问by Drwhite

I have tried to compare those two JSON objects:

我试图比较这两个 JSON 对象:

<input type="hidden" id="remoteJSON" name="remoteJSON" value='{"allowExternalMembers": "false", "whoCanJoin": "CAN_REQUEST_TO_JOIN"}' /><br />
<input type="hidden" id="localJSON" name="localJSON" value='{"whoCanJoin": "CAN_REQUEST_TO_JOIN", "allowExternalMembers": "false"}' /><br />

I got values with javascript and I tried to compare with : JSON.stringify(remoteJSON) == JSON.stringify(localJSON)but this return false: it seems that the order of the properties is important.

我使用 javascript 获取了值,并尝试与 : 进行比较,JSON.stringify(remoteJSON) == JSON.stringify(localJSON)但这返回 false: 似乎属性的顺序很重要。

And I even tried deep compare with this solutionand always got a false return.

我什至尝试与此解决方案进行深入比较,总是得到错误的回报。

Is there a fast way to do the issue with jQuery (i.e. libraries for comparing JSON) ?

有没有一种快速的方法来解决 jQuery(即用于比较 JSON 的库)的问题?

回答by Nicolas

Lodash _.isEqualallows you to do that:

Lodash_.isEqual允许你这样做:

var
remoteJSON = {"allowExternalMembers": "false", "whoCanJoin": "CAN_REQUEST_TO_JOIN"},
    localJSON = {"whoCanJoin": "CAN_REQUEST_TO_JOIN", "allowExternalMembers": "false"};
    
console.log( _.isEqual(remoteJSON, localJSON) );
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

回答by Samadhan Sakhale

Easy way to compare two json string in javascript

在javascript中比较两个json字符串的简单方法

var obj1 = {"name":"Sam","class":"MCA"};
var obj2 = {"class":"MCA","name":"Sam"};

var flag=true;

if(Object.keys(obj1).length==Object.keys(obj2).length){
    for(key in obj1) { 
        if(obj1[key] == obj2[key]) {
            continue;
        }
        else {
            flag=false;
            break;
        }
    }
}
else {
    flag=false;
}
console.log("is object equal"+flag);

回答by Ashita.gupta

Lodash isEqual()method is the best way to compare two JSON object.

LodashisEqual()方法是比较两个 JSON 对象的最佳方法。

This will not consider the order of the keys in object and check for the equality of object. Example

这不会考虑对象中键的顺序并检查对象的相等性。例子

const object1={
name:'ABC',
address:'India'
}

const object2={
address:'India',
name:'ABC'
}

JSON.stringify(object1)===JSON.stringify(object2)
// false

_.isEqual(object1, object2)
//true

Reference-https://lodash.com/docs/#isEqual

参考 - https://lodash.com/docs/#isEqual

If sequence is not going to change than JSON.stringify()will be fast as compared to Lodash isEqual()method

如果序列不会改变,JSON.stringify()那么与 LodashisEqual()方法相比会更快

Reference-https://www.measurethat.net/Benchmarks/Show/1854/0/lodash-isequal-test

参考 - https://www.measurethat.net/Benchmarks/Show/1854/0/lodash-isequal-test

回答by Thomas John

lodash will work, tested even for angular 5, http://jsfiddle.net/L5qrfx3x/

lodash 可以工作,甚至可以测试 angular 5,http://jsfiddle.net/L5qrfx3x/

var remoteJSON = {"allowExternalMembers": "false", "whoCanJoin": 
   "CAN_REQUEST_TO_JOIN"};
var localJSON = {"whoCanJoin": "CAN_REQUEST_TO_JOIN", 
  "allowExternalMembers": "false"};

 if(_.isEqual(remoteJSON, localJSON)){
     //TODO
    }

it works, for installation in angular, follow this

它有效,对于角度安装,请遵循

回答by Giannis Grivas

This question reminds of how to determine equalityfor two JavaScript objects. So, I would choose thisgeneral function

这个问题提醒了如何确定两个JavaScript 对象的相等性。所以,我会选择这个通用功能

Compares JS objects:

比较 JS 对象:

function objectEquals(x, y) {
    // if both are function
    if (x instanceof Function) {
        if (y instanceof Function) {
            return x.toString() === y.toString();
        }
        return false;
    }
    if (x === null || x === undefined || y === null || y === undefined) { return x === y; }
    if (x === y || x.valueOf() === y.valueOf()) { return true; }

    // if one of them is date, they must had equal valueOf
    if (x instanceof Date) { return false; }
    if (y instanceof Date) { return false; }

    // if they are not function or strictly equal, they both need to be Objects
    if (!(x instanceof Object)) { return false; }
    if (!(y instanceof Object)) { return false; }

    var p = Object.keys(x);
    return Object.keys(y).every(function (i) { return p.indexOf(i) !== -1; }) ?
            p.every(function (i) { return objectEquals(x[i], y[i]); }) : false;
}

回答by Hassan Alvi

In VueJs function you can use this as well... A working solution using recursion. Base credits Samadhan Sakhale

在 VueJs 函数中,您也可以使用它......使用递归的工作解决方案。基础学分 Samadhan Sakhale

     check_objects(obj1, obj2) {
            try {
                var flag = true;

                if (Object.keys(obj1).length == Object.keys(obj2).length) {
                    for (let key in obj1) {

                        if(typeof (obj1[key]) != typeof (obj2[key]))
                        {
                            return false;
                        }

                        if (obj1[key] == obj2[key]) {
                            continue;
                        }

                        else if(typeof (obj1[key]) == typeof (new Object()))
                        {
                            if(!this.check_objects(obj1[key], obj2[key])) {
                                return false;
                            }
                        }
                        else {
                            return false;
                        }
                    }
                }
                else {
                    return false
                }
            }
            catch {

                return false;
            }

            return flag;
        },

回答by TmTron

We use the node-deep-equalproject which implements the same deep-equal comparison as nodejs

我们使用node-deep-equal项目,它实现了与nodejs相同的深度相等比较

A google serach for deep-equal on npmwill show you many alternatives

一个谷歌检索算法对NPM深等于会告诉你许多选择

回答by Amjad Abujamous

I adapted and modified the code from this tutorialto write a function that does a deep comparison of two JS objects.

我改编并修改了本教程中的代码,编写了一个对两个 JS 对象进行深入比较的函数。

const isEqual = function(obj1, obj2) {
    const obj1Keys = Object.keys(obj1);
    const obj2Keys = Object.keys(obj2);

    if(obj1Keys.length !== obj2Keys.length) {
        return false;
    }

    for (let objKey of obj1Keys) {
        if (obj1[objKey] !== obj2[objKey]) {
            if(typeof obj1[objKey] == "object" && typeof obj2[objKey] == "object") {
                if(!isEqual(obj1[objKey], obj2[objKey])) {
                    return false;
                }
            } 
            else {
                return false;
            }
        }
    }

    return true;
};

The function compares the respective values of the same keys for the two objects. Further, if the two values are objects, it uses recursion to execute deep comparison on them as well.

该函数比较两个对象的相同键的各自值。此外,如果这两个值是对象,它也会使用递归对它们执行深度比较。

Hope this helps.

希望这可以帮助。

回答by ajit jain

DeepCompare method to compare two json objects..

DeepCompare 方法来比较两个 json 对象..

deepCompare = (arg1, arg2) => {
  if (Object.prototype.toString.call(arg1) === Object.prototype.toString.call(arg2)){
    if (Object.prototype.toString.call(arg1) === '[object Object]' || Object.prototype.toString.call(arg1) === '[object Array]' ){
      if (Object.keys(arg1).length !== Object.keys(arg2).length ){
        return false;
      }
      return (Object.keys(arg1).every(function(key){
        return deepCompare(arg1[key],arg2[key]);
      }));
    }
    return (arg1===arg2);
  }
  return false;
}

console.log(deepCompare({a:1},{a:'1'})) // false
console.log(deepCompare({a:1},{a:1}))   // true

回答by Drwhite

Due to @zerkems comment:

由于@zerkems 评论:

i should convert my strings to JSON object and then call the equal method:

我应该将我的字符串转换为 JSON 对象,然后调用 equal 方法:

var x = eval("(" + remoteJSON + ')');
var y = eval("(" + localJSON + ')');

function jsonequals(x, y) {
    // If both x and y are null or undefined and exactly the same
    if ( x === y ) {
        return true;
    }

    // If they are not strictly equal, they both need to be Objects
    if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) {
        return false;
    }

    // They must have the exact same prototype chain, the closest we can do is
    // test the constructor.
    if ( x.constructor !== y.constructor ) {
        return false;
    }

    for ( var p in x ) {
        // Inherited properties were tested using x.constructor === y.constructor
        if ( x.hasOwnProperty( p ) ) {
            // Allows comparing x[ p ] and y[ p ] when set to undefined
            if ( ! y.hasOwnProperty( p ) ) {
                return false;
            }

            // If they have the same strict value or identity then they are equal
            if ( x[ p ] === y[ p ] ) {
                continue;
            }

            // Numbers, Strings, Functions, Booleans must be strictly equal
            if ( typeof( x[ p ] ) !== "object" ) {
                return false;
            }

            // Objects and Arrays must be tested recursively
            if ( !equals( x[ p ],  y[ p ] ) ) {
                return false;
            }
        }
    }

    for ( p in y ) {
        // allows x[ p ] to be set to undefined
        if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) {
            return false;
        }
    }
    return true;
}