【问题标题】:Compare structure of json objects javascript比较json对象javascript的结构
【发布时间】:2017-06-18 21:50:03
【问题描述】:

我正在写一个测试函数 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

但是

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

【问题讨论】:

  • 在 JavaScript 中,没有 char 数组或 number 数组这样的东西。因此,您需要首先定义两个数组是否为“相同类型”的含义。你会考虑哪种类型的["a", 2]?和[1, "b"]是同一类型吗?
  • 只需创建函数(声明要检查的规则)并循环遍历您的 json 对象:)
  • @smarx 我的数组将包含 JSON,我假设所有数组都将具有相同的 json 类型。我会稍微编辑一下问题
  • @AgentWeirdo 如果我理解正确,您只需检查数组的第一个元素,然后检查是否匹配。看来您已经准备好开始编写代码了! :-) 如果/当您有需要帮助的具体问题时,请告诉我们。

标签: javascript json postman


【解决方案1】:

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

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

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&2、1&3、1&4、1&5、1&6 和 1&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);

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 2023-03-26
    • 2013-05-25
    • 2011-12-27
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2019-12-25
    • 2018-03-23
    相关资源
    最近更新 更多