【问题标题】:How do I verify if several attributes are in a JSON structure within JavaScript?如何验证 JavaScript 中的 JSON 结构中是否有多个属性?
【发布时间】:2013-05-06 13:15:56
【问题描述】:

我正在创建一个接收多个复杂 JSON 文件的模块,如果某些元素不存在,我想要一些代码来给用户反馈。

下面是我现在做的方式,但我不禁想到一定有一种更清洁、更简洁的方式。

var _und = require("underscore");
//this function takes a list of required attributes and ensures they are present
var check_req_attr = function(config, req_attr, callback) {
    var config_attr = Object.keys(config);
    var absent_attr = _und.difference(req_attr, config_attr); //slightly hacky code that checks to ensure config has correct vars
    if (absent_attr.length !== 0) {
        throw Error("missing following attributes from config:" + absent_attr);
    } else {
        callback();
    };
};

只是感觉……脏。如果没有真正优雅的方式来做到这一点,我愿意接受对我的代码的批评。谢谢!

【问题讨论】:

    标签: javascript json node.js validation


    【解决方案1】:
    1. 将 JSON 解析为 JS。

      var data = JSON.parse(theJson);

    2. 使用类似的东西:

      function hasKey(obj, key) {
          return typeof obj[key] !== 'undefined';
      };
      
      
      
      function hasKeys(obj, keys) {
      
          for (var i = 1, len = keys.length; i < len; i++) {
              if (!hasKey(obj, keys[i])) {
                  return false;
              };
          };
          return true;
      };
      

    现在你可以简单地做:

    if (hasKeys(data, ["firstKey", "secondKey", "thirdKey"]) {
        console.log("valid");
    };
    

    【讨论】:

    • 请注意,这不适用于层次结构。例如,您不能使用此方法来测试a.b.c,除非您的意图是它们的键被专门称为b.c,而不是通常的“b 是a 的子对象,c 是b 的键”。跨度>
    【解决方案2】:

    这应该是这样做的方式,使用everyhas

    if (_und.every(req_attr, function(attr) {
        return _und.has(config, attr);
    }))
        throw new Error();
    

    在原生环境中,您只需使用in operator

    req_attr.every(function(attr){ return attr in config; })
    

    【讨论】:

    • @alex23: 那个操作符有什么不一致的地方?为什么会误导?它完全按照需要执行,检查属性是否存在。
    【解决方案3】:

    我认为您的解决方案实际上非常优雅!不需要匿名函数,循环(显然必须在某个时候发生)用difference 巧妙地抽象出来。

    两个建议:

    1. 我会给函数一个同步签名。没有回调参数。如果您尊重函数签名(即仅基于configreq_attr 的答案),就没有任何理由去异步。

    2. 我会更改函数以返回缺少的属性(属性是错误的术语)。您还可以添加一个requireProperties 函数,该函数使用此“检查”函数,如果缺少属性,该函数将抛出。这允许不同类型的用途。

    【讨论】:

      【解决方案4】:

      你为什么不试试类似的东西:

      obj = JSON.parse(json);
      

      然后检查

      if(obj.YourProperty == undefined){
          //do something..
      }
      

      希望我理解你的问题。它也应该适用于复杂的 JSON 文件。祝你好运 ;)

      【讨论】:

      • 抱歉检查了多个属性
      • 如果您将多个属性检查到一个层次结构中,您可以简单地用一个通过解析的 JSON 对象的函数覆盖我的“if”..
      【解决方案5】:

      您也可以使用in 运算符 (requiredAttr in obj):

      function objHasAllRequiredAttrs(obj, attrNames) {
        return attrNames.reduce(function(memo, attrName) {
          return memo && (attrName in obj);
        }, true);
      }
      
      objHasAllRequiredAttrs({foo:1}, ['foo']); // => true
      objHasAllRequiredAttrs({bar:1}, ['foo']); // => false
      

      【讨论】:

      • 为什么是reduceevery 正是那个用例。
      • @Bergi:另一个答案已经提到every,我想提供另一种选择,只是为了多样性。另外,我没有在标签中看到“underscore.js”,所以我想坚持纯 JS。
      猜你喜欢
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 2017-08-16
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多