比较json对象javascript的结构

时间:2017-06-17 22:21:11

标签: javascript json postman

我正在编写测试函数邮递员,以检查json对象是否具有相同的密钥,并且每个密钥具有相同的数据类型

我有3个json对象

var test1 = {
    "abc" : 1,
    "qwe" : "random",
    "arrayExample" : [{"var1" : 11, "var2" : 22}, {"var1" : 21314, "var2" : 99}]
}


var test2 = {
    "abc" : 3,
    "qwe" : "Another String",
    "arrayExample" : [{"var1": 435, "var2": 897}]
}


var test3 = {
    "abc" : 46,
    "qwe" : "Nothing special",
    "arrayExample" : [{"var1": 098, "var9" : "string here"}]
}

我想测试一下密钥,每个密钥的值也是同一类型。

例如,如果我的比较函数名为compare,如果对象属于同一类型,则返回true,

function compare(obj1, obj2){
    <NEED HELP HERE>
}

然后我需要

compare(test1, test2) == true

compare(test1, test3) == compare(test2, test3) == false

,因为

typeOf( test1["arrayExample"] ) = typeOf( test2["arrayExample"] ) = array of same JSON type

BUT

typeOf( test3["arrayExample"]) = array of different json type

1 个答案:

答案 0 :(得分:0)

如果您的问题仅涉及比较各个属性值,则可以执行以下操作:

  • 确保两个对象具有相同数量的键。
  • 确保同名属性的值类型相同。

const tests = {
  4: {a: 1, b: "AA"},
  5: {b: "BB", a: 2},
  6: {a: 3, b: 999},
  7: {a: 4, c: "CC"},
  8: {a: 5, b: "DD", c: 999},
  9: {a: 6, b: "EE", c: undefined}
};

const compare = (obj1, obj2) => {
  let similar = true;
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Object.keys(obj2);
  if (obj1Keys.length !== obj2Keys.length) {
    similar = false;
  } else {
    obj1Keys.forEach(key => {
      similar = (typeof obj1[key] === typeof obj2[key]);
    });
  }
  return similar;
};

const check = (a, b) => {
  console.log(`Test objects ${a} and ${b} are similar? ${compare(tests[a], tests[b])}`);
};

check(4, 5);
check(4, 6);
check(4, 7);
check(4, 8);
check(4, 9);

但是,对于数组属性,您可以对来自两个对象的同名属性数组中的所有数组元素组合使用整个上述过程进行递归检查。例如如果对象1的属性“X”具有3个对象的数组,对象2的属性“X”具有4个对象的数组(总共7个对象),则递归使用上述检查来比较这7个对象中的第一个对抗所有其他6个,即比较1&amp; 2,1和3,1和4,1&amp; 5,1&amp; 6和1&amp; 7。

虽然我没有对它进行测试,虽然你的问题实际上没有问过这个问题,但这种方法实际上甚至可以用于子嵌套的对象数组,即如果一个数组包含自身包含对象数组的对象,这是因为代码的(可能是无限的)递归性质。

const tests = {
  1: {
    "abc" : 1,
    "qwe" : "random",
    "arrayExample" : [{"var1" : 11, "var2" : 22}, {"var1" : 21314, "var2" : 99}]
  },
  2: {
    "abc" : 3,
    "qwe" : "Another String",
    "arrayExample" : [{"var1": 435, "var2": 897}]
  },
  3: {
    "abc" : 46,
    "qwe" : "Nothing special",
    "arrayExample" : [{"var1": 098, "var9" : "string here"}]
  },
  
  11: {d: 11, e: [{f: 12, g: "FF"}, {f: 13, g: "GG"}                  ]},
  12: {d: 14, e: [{f: 15, g: "HH"}, {f: 16, g: "II"}, {f: 17, g: "JJ"}]},
  13: {d: 18, e: [{g: "KK", f: 19}                                    ]},
  14: {d: "", e: [{f: 20, g: "LL"}                                    ]},
  15: {d: 21, e: [{f: 22, g: 23  }                                    ]},
  16: {d: 24, e: [{f: 25, h: "MM"}                                    ]},
  17: {d: 26, e: [{f: 27, g: "MM", h: 28}                             ]},
};

const compare = (obj1, obj2) => {
  let similar = true;
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Object.keys(obj2);
  if (obj1Keys.length !== obj2Keys.length) {
    similar = false;
  } else {
    obj1Keys.forEach(key => {
      const val1 = obj1[key], val2 = obj2[key];
      if (Array.isArray(val1) === true) {
        if (Array.isArray(val2) === false) {
          similar = false;
        } else {
          const allSubObjs = [].concat(
            Object.keys(val1).map(subKey => val1[subKey]),
            Object.keys(val2).map(subKey => val2[subKey])
          );
          allSubObjs.splice(1).forEach(subObj => {
            const recursiveCheck = compare(allSubObjs[0], subObj);
            if (recursiveCheck === false) similar = false;
          });
        }
      } else if (typeof val1 !== typeof val2) similar = false;
    });
  }
  return similar;
};

const check = (a, b) => {
  console.log(`Test objects ${a} and ${b} are similar? ${compare(tests[a], tests[b])}`);
};

check(1, 2);
check(1, 3);
check(2, 3);

check(11, 12);
check(11, 13);
check(11, 14);
check(11, 15);
check(11, 16);
check(11, 17);