【问题标题】:check the existence of a key in associative arrays检查关联数组中是否存在键
【发布时间】:2017-09-05 05:01:17
【问题描述】:

告诉我,如何正确地检查关联数组中键的存在?

例如:

var mydata = {
    key1: '',
    key2: {
        subkey1: {
            subkey1_1: {
                value1: ''
                value2" '',
            },
        },
        subkey2: '';
    },
}

if ((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined))
    mydata.key2.subkey1.subkey1_1.value1 = 'test';

太长太混乱了

((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined))

我想用一个更简单的函数,比如

safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test');

if (is_undefined(mydata.key2.subkey1.subkey1_1.value1) == true)
    mydata.key2.subkey1.subkey1_1.value1 = 'test'; // now - error if 'mydata.key2.subkey1.subkey1_1' not exist

【问题讨论】:

  • associative arrays?你的意思是"object"
  • 您要检查键是否存在,或者键是否有值?你的问题是前者,你的代码暗示后者。无论哪种方式,听起来您都可以使用 try/catch

标签: javascript jquery undefined associative-array exists


【解决方案1】:

您可以使用reduce() 创建自定义函数来测试嵌套属性是否存在。您可以将密钥作为字符串传递。

var mydata = {
  key1: '',
  key2: {
    subkey1: {
      subkey1_1: {
        value1: '',
        value2: '',
      },
    },
    subkey2: ''
  },
}

function safeSet(key, data) {
  return key.split('.').reduce(function(r, e) {
    return r ? r[e] : undefined;
  }, data) != undefined
}

console.log(safeSet('key2.subkey1.subkey1_1.value1', mydata))

【讨论】:

    【解决方案2】:

    你应该使用 in 操作符:

    "key" in obj // true, regardless of the actual value
    

    或者,如果您想特别测试对象实例的属性(而不是继承的属性),请使用hasOwnProperty:

    obj.hasOwnProperty("key") // true
    

    希望这会对你有所帮助。

    来源:http://www.advancesharp.com/questions/628/checking-if-an-associative-array-key-exists-in-javascript

    【讨论】:

    • 如果您要查找的密钥有几个层次,obj.hasOwnProperty("key") 会有什么用处?
    【解决方案3】:

    或者,您可以使用Lodash.has() 方法。 然后,您只需要检查:

    if (_.has(mydata, 'key2.subkey1.subkey1_1.value1')
        mydata.key2.subkey1.subkey1_1.value1 = 'test';
    

    【讨论】:

      【解决方案4】:

      为了尝试在嵌套结构中获取某些内容,我会这样做:

      function getPath(element, path) {
          var handledSoFar = [];
          for (var i = 0; i < path.length; i++) {
              var property = path[i];
              handledSoFar.push(property);
              if (typeof element[property] === 'undefined') {
                  throw new Error('Path ' + handledSoFar.join('->') + ' is undefined');
              }
              element = object[property];
          }
          return element;
      }
      
      var mydata = {
          key1: '',
          key2: {
              subkey1: {
                  subkey1_1: {
                      value1: '',
                      value2: 'hi'
                  }
              },
              subkey2: ''
          }
      };
      
      // Prints 'hi'
      console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2']));
      
      // Throws error 'Path key2->subkey2->subkey1_1 is undefined'
      console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2']));
      

      当然,跟踪handledSoFar 中的搜索是可选的,但可能对开发/调试有用。

      【讨论】:

        【解决方案5】:

        您也可以使用 lodash 深场选择器:lodash.get (documentation)

        const get = require('lodash.get');
        const set = require('lodash.set');
        
        if (!get(mydata, 'key2.subkey1.subkey1_1.value1')) {
            set(mydata, 'key2.subkey1.subkey1_1.value1', 'test');
        }
        

        【讨论】:

          【解决方案6】:

          您可以拆分路径并检查以下元素是否存在。如果没有将对象分配给新属性。

          然后返回属性的值。

          最后赋值。

          function setValue(object, path, value) {
              var fullPath = path.split('.'),
                  way = fullPath.slice(),
                  last = way.pop();
          
              way.reduce(function (r, a) {
                  return r[a] = r[a] || {};
              }, object)[last] = value;
          }
          
          var object = { key1: '', key2: { subkey1: { subkey1_1: { value1: '', value2: '' } }, subkey2: '' } };
          
          setValue(object, 'key2.subkey1.subkey1_1.value1', 'test');
          console.log(object);

          【讨论】:

            【解决方案7】:

            您提出的示例函数的问题:

            safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test');
            

            is_undefined(mydata.key2.subkey1.subkey1_1.value1)
            

            mydata.key2.subkey1... 部分是否在调用函数之前运行。因此,如果其中一个子键不存在,则会在到达您的代码之前引发异常。

            你可以使用回调获得类似的东西......

            safeSet(function(val) { mydata.key2.subkey1.subkey1_1.value1 = val; }, 'test')
            

            safeSet 的实现将是:

            var safeSet = function(setterFunc, val) {
              try {
                setterFunc(val);
              } catch (e) {
                if (e instanceof TypeError) {
                  return false;
                } else {
                  throw e;
                }
              }
              return true;
            }
            

            如果设置了值,safeSet 返回 true,否则返回 false。

            【讨论】:

              猜你喜欢
              • 2020-04-11
              • 1970-01-01
              • 2012-08-02
              • 2015-10-09
              • 2018-02-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多