programing

순서 없이 동일한 속성을 가진 두 JSON을 비교하려면 어떻게 해야 합니까?

starjava 2023. 3. 8. 20:32
반응형

순서 없이 동일한 속성을 가진 두 JSON을 비교하려면 어떻게 해야 합니까?

이 두 개의 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)그러나 이 반환은 거짓입니다.을 사용법

그리고 이 솔루션과 자세히 비교해보니 항상 잘못된 결과가 나왔습니다.

jQuery(JSON을 비교하는 라이브러리)에서 문제를 신속하게 해결할 수 있는 방법이 있습니까?

Lodash는 다음과 같은 이점을 제공합니다.

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>

isEqual()메서드 2의 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

가 「」보다 하지 않는 .JSON.stringify()Lodash에 가 빠릅니다.isEqual()★★★★★★ 。

레퍼런스 - https://www.measurethat.net/Benchmarks/Show/1854/0/lodash-isequal-test

두 json 개체를 비교하는 DeepCompare 메서드입니다.

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

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

튜토리얼의 코드를 수정하여 JS 오브젝트 2개를 상세하게 비교하는 함수를 작성했습니다.

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

함수는 두 개체에 대해 동일한 키의 각 값을 비교합니다.또, 2개의 값이 오브젝트인 경우는, 재귀도 사용해 그것들을 상세하게 비교합니다.

이게 도움이 됐으면 좋겠다.

lodash는 각도가 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
    }

각도로 설치할 경우 다음과 같이 하십시오.

이 함수는 단순한 프리미티브가 있는 개체에 대해 작동합니다.

function compareObjects(o1, o2) {
  const normalizedObj1 = Object.fromEntries(Object.entries(o1).sort(([k1], [k2]) => k1. localeCompare(k2)));
  const normalizedObj2 = Object.fromEntries(Object.entries(o2).sort(([k1], [k2]) => k1. localeCompare(k2)));
  return JSON.stringify(normalizedObj1) === JSON.stringify(normalizedObj2);
}

compareObjects({a: 1, b: 2}, {b: 2, a: 1}); // true

오브젝트에 네스트된 오브젝트가 포함되어 있는 경우 재귀적으로 정규화할 필요가 있기 때문에 동작하지 않습니다.

이 질문은 두 개의 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;
        },

nodejs와 동일한 심층 비교를 구현하는 노드-deep-equal 프로젝트를 사용합니다.

npm의 deep equal에 대한 구글 검색은 많은 대안을 보여줍니다.

이 두 개체를 동일한 목표로 비교하려는 경우, 즉 유효한 개체만 역직렬화하는 경우 다음 방법을 사용할 것을 권장합니다.

using Newtonsoft.Json;

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

오류가 발견되면 개체는 YourTargetObjectType에 속하지 않습니다.그렇지 않으면 두 번째 개체에 대해서도 동일한 작업을 수행할 수 있습니다.

Missing Member Handling을 가진 Json Serializer Settings가 이 기능을 수행합니다.또한 mme 예외 개체에서 실패한 속성도 확인할 수 있습니다.그러면 추가 속성, 누락된 속성 및/또는 철자가 잘못된 속성이 검증됩니다.

따라서 이 경우 두 개체를 비교하는 데 참조로 사용되는 개체가 있어야 합니다.

이 목적을 위한 Intelij Idea 플러그인이 있습니다.https://plugins.jetbrains.com/plugin/20169-json-comparator?preview=true 이 플러그인은 어레이 내의 모든 필드와 개체를 재귀적으로 정렬합니다.

JSONata의 경우 = 연산자를 사용하면 됩니다.

async function compare() {
  const jsonEQObj = {
    object1: {
      name: 'ABC',
      address: 'India'
    },
    object2: {
      address: 'India',
      name: 'ABC'
    }
  };
  let isEqual = await jsonata('object1=object2').evaluate(jsonEQObj)
  console.log(isEqual)

  jsonEQObj.object1.name = 'X';
  isEqual = await jsonata('object1=object2').evaluate(jsonEQObj)
  console.log(isEqual)
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>JSONata test</title>
  <script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
</head>

<body onload=compare()>
</body>

</html>

@zerkems 코멘트로 인해:

문자열을 JSON 개체로 변환한 후 동일한 메서드를 호출해야 합니다.

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

언급URL : https://stackoverflow.com/questions/26049303/how-to-compare-two-json-have-the-same-properties-without-order

반응형