繁体   English   中英

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

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

我试图比较这两个 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 />

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

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

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

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/lodash@4.17.10/lodash.min.js"></script>

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

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

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

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

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

_.isEqual(object1, object2)
//true

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

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

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

在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);

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

此代码将独立于 param 对象顺序验证 json。

 var isEqualsJson = (obj1,obj2)=>{ keys1 = Object.keys(obj1); keys2 = Object.keys(obj2); //return true when the two json has same length and all the properties has same value key by key return keys1.length === keys2.length && Object.keys(obj1).every(key=>obj1[key]==obj2[key]); } var obj1 = {a:1,b:2,c:3}; var obj2 = {a:1,b:2,c:3}; console.log("json is equals: "+ isEqualsJson(obj1,obj2)); alert("json is equals: "+ isEqualsJson(obj1,obj2));

我改编并修改了本教程中的代码,编写了一个对两个 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;
};

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

希望这可以帮助。

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
    }

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

这个问题让人想起如何确定两个JavaScript 对象的相等性 所以,我会选择这个通用功能

比较 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;
}

在 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;
        },

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

在 npm 上进行 deep-equal 的 google serach将向您展示许多替代方案

如果您尝试将这两个对象与我的目标相同:即反序列化一个有效对象,在这种情况下,我建议您使用以下方法:

using Newtonsoft.Json;

try
{
    var myObj = JsonConvert.DeserializeObject<**YourTargetObjectType**>(jsonString, new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        MissingMemberHandling = MissingMemberHandling.Error
    });
}catch (MissingMemberException mme)
{
    
    throw;
}

如果错误被捕获,那么您的对象不属于YourTargetObjectType 否则最好去,你可以对第二个对象做同样的事情。

带有 MissingMemberHandling 的 JsonSerializerSetings 可以解决问题。 在 mme 异常对象中,您可以检查哪个属性属性失败。 这会验证额外的属性、缺失的属性和/或拼写错误的属性。

因此,在您的情况下,您应该有一个对象,它将用作比较两个对象的参考。

由于@zerkems 评论:

我应该将我的字符串转换为 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM