javascript как сравнивать только ключи, а не значения json - PullRequest
0 голосов
/ 08 мая 2020

У меня есть два вложенных объекта JSON

//Json object1
{
    "version": "1",
    "user": {
        "id": 123
    }
}
//Json object2 =
{
    "version": "1",
    "user": {
        "i": 123
    }
}

1) Он должен проверять только ключи, а не значения во время сравнения. Таким образом, приведенное выше должно возвращать false, а ниже должно возвращать true 2) Он также должен соответствовать структуре, например, user.id - это не то же самое, что просто id.

//Json object1 
{
    "version": "1",
    "user": {
        "id": 123
    }
}
//Json object2
{
    "version": "1",
    "user": {
        "id": 12
    }
}

Я пробовал код ниже, но безрезультатно

exports.compareObjects = async(model, response) => {

      switch (Object.prototype.toString.call(model)) {
          case '[object]':
              var x;
              var mKeys = Object.keys(model);
              for (x in mKeys) {
                  return this.compareObjects(Object.keys(model)[x], Object.keys(response)[x]);
              }
              break;
              case '[object Object]':
                var x1;
                var mKeys1 = Object.keys(model);
                for (x1 in mKeys1) {
                    return this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);
                }
                break;
          case '[object Array]':
              return this.compareObjects(model[0], response[0]);

          // case '[object String]':
          //     return model === response;

          default:
              return true;
      }
};


Ответы [ 3 ]

1 голос
/ 08 мая 2020

Используется рекурсивный поиск ключей для построения массива ключей в каждом объекте, который вы хотите сравнить.

Он проверяет довольно строгое равенство (без дополнительных ключей ни в одном из объектов)

let obj1 = JSON.parse(`{
    "version": "1",
    "user": {
        "id": 123
    }
}`);

let obj2 = JSON.parse(`{
    "version": "1",
    "user": {
        "i": 123
    }
}`);

let obj3 = JSON.parse(`{
    "version": "1",
    "user": {
        "id": 123
    }
}`);

let obj4 = JSON.parse(`{
    "version": "1",
    "user": {
        "id": 12
    }
}`);

let test1 = structureIsEqual(obj1, obj2);
let test2 = structureIsEqual(obj3, obj4);

console.log('Structure of first two match: ' + test1);
console.log('Structure of second two match: ' + test2);

function structureIsEqual(obj1, obj2) {
  let tree1 = getKeys(obj1).sort();
  let tree2 = getKeys(obj2).sort();
  
  if(tree1.length !== tree2.length)
    return false;
  
  let mismatch = tree1.find((x, idx) => tree2[idx] !== x);
  return !mismatch;
}

function getKeys(obj) {
  return recursiveKeys(obj, [], []);  
}

function recursiveKeys(obj, result, todo, root = '') {  
  Object.keys(obj).forEach(key => {
    if(typeof obj[key] === 'object') {      
      result.push(root + key);
      todo.push({ obj: obj[key], root: root + key + '.' });      
    } else {
      result.push(root + key);
    }
  });
  
  if(todo.length > 0) {
    let todoItem = todo.pop();
    return recursiveKeys(todoItem.obj, result, todo, todoItem.root);
  }else {
    return result;
  }
}
0 голосов
/ 08 мая 2020
        var compareObjects = (model, response) => {
      switch (Object.prototype.toString.call(model)) {
          case '[object]':
              var x;
              var mKeys = Object.keys(model);
              for (x in mKeys) {
                  return this.compareObjects(Object.keys(model)[x], Object.keys(response)[x]);
              }
              break;
              case '[object Object]':
                var x1;
                var mKeys1 = Object.keys(model);

                for (x1 in mKeys1) {
                    let t = this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);
                    if(!t){
                      return false
                    }

                    if(typeof model[mKeys1[x1]] == "object"){
                     return this.compareObjects(model[mKeys1[x1]], response[mKeys1[x1]])
                    }


                }

          case '[object Array]':
              return this.compareObjects(model[0], response[0]);

          case '[object String]':
              return model === response;

          default:
              return true;
      }
};
let a = {
    "version": "1",
    "user": {
        "id": 123,
        "n":"d",
         "j":{
          "ns":"m"
        }
    }
}
let b = {
    "version": "1",
    "user": {
        "id": 123,
        "n":"d",
        "j":{
          "ns":"m"
        }
    }
}
var t = compareObjects(a,b)
console.log(t)
0 голосов
/ 08 мая 2020

Может быть, вы могли бы исправить это с помощью этой строки

return this.compareObjects(Object.keys(model)[x1], Object.keys(response)[x1]);

Вместо этого сделайте

return this.compareObjects(model[x1], response[x1]);

Я бы сделал это так 1. вам нужно только сравнивать объекты (все остальные не есть ключи) 2. рекурсивно, если значение также является объектом

function compare(obj,model){
let keys=Object.keys(model)
let thisLevelOK=true
for (let key in keys.length){
if (obj[key]===undefined){
thisLevelOK=false
break
} else if (model[key].toString()=="[object Object]"  && compare(obj[key],model[key])==false){
thisLevelOK=false
break
}
}
//in case obj has more keys then model
thisLevelOK=thisLevelOK && compare(model,obj)
return thisLevelOK
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...