简体   繁体   English

javascript相当于python的dictionary.get

[英]javascript equivalent to python's dictionary.get

I'm trying to validate a JSON object with node.js. 我正在尝试使用node.js验证JSON对象。 Basically, if condition A is present then I want to make sure that a particular value is in an array which may not be present. 基本上,如果存在条件A,那么我想确保特定值在可能不存在的数组中。 I do this in python using dictionary.get because that will return a default value if I look up something that isn't present. 我在python中使用dictionary.get执行此操作,因为如果我查找不存在的内容,它将返回默认值。 This is what it looks like in python 这就是它在python中的样子

if output.get('conditionA') and not 'conditionB' in output.get('deeply', {}).get('nested', {}).get('array', []):
    print "There is an error somewhere you need to be fixing."

I'd like to find a similar technique for javascript. 我想找到一个类似的javascript技术。 I tried using defaults in underscore to create the keys if they aren't there but I don't think I did it right or I'm not using it the way it was intended. 我尝试使用下划线中的默认值来创建密钥,如果它们不在那里,但我不认为我做得对,或者我没有按照预期的方式使用它。

var temp = _.defaults(output, {'deeply': {'nested': {'array': []}}});
if (temp.hasOwnProperty('conditionA') && temp.deeply.nested.array.indexOf('conditionB') == -1) {
    console.log("There is an error somewhere you need to be fixing.");
}

It seems like if it runs into an output where one of the nested objects is missing it doesn't replace it with a default value and instead blows with a TypeError: Cannot read property 'variety' of undefined where 'variety' is the name of the array I'm looking at. 看起来如果它遇到其中一个嵌套对象丢失的输出,它不会用默认值替换它而是用TypeError: Cannot read property 'variety' of undefined打击TypeError: Cannot read property 'variety' of undefined其中'variety'是其名称我正在看的阵列。

Or better yet, here's a quick wrapper that imitates the functionality of the python dictionary. 或者更好的是,这是一个模仿python字典功能的快速包装器。

http://jsfiddle.net/xg6xb87m/4/ http://jsfiddle.net/xg6xb87m/4/

function pydict (item) {
    if(!(this instanceof pydict)) {
       return new pydict(item);
    }
    var self = this;
    self._item = item;
    self.get = function(name, def) {
        var val = self._item[name];
        return new pydict(val === undefined || val === null ? def : val);
    };
    self.value = function() {
       return self._item;
    };
    return self;
};
// now use it by wrapping your js object
var output = {deeply: { nested: { array: [] } } };
var array = pydict(output).get('deeply', {}).get('nested', {}).get('array', []).value();

Edit 编辑

Also, here's a quick and dirty way to do the nested / multiple conditionals: 此外,这是一个快速而肮脏的方法来执行嵌套/多个条件:

var output = {deeply: {nested: {array: ['conditionB']}}};
var val = output["deeply"]
if(val && (val = val["nested"]) && (val = val["array"]) && (val.indexOf("conditionB") >= 0)) {
...
}

Edit 2 updated the code based on Bergi's observations. 编辑2根据Bergi的观察更新了代码。

The standard technique for this in JS is (since your expected objects are all truthy) to use the || JS中的标准技术是(因为你的预期对象都是真实的)使用|| operator for default values: 运算符的默认值:

if (output.conditionA && (((output.deeply || {}).nested || {}).array || []).indexOf('conditionB') == -1) {
    console.log("There is an error somewhere you need to be fixing.")
}

The problem with your use of _.defaults is that it's not recursive - it doesn't work on deeply nested objects. 使用_.defaults的问题在于它不是递归的 - 它不适用于深层嵌套的对象。

You can check that a key exists easily in javascript by accessing it. 您可以通过访问它来检查javascript中是否存在密钥。

if (output["conditionA"]) {
  if(output["deeply"]) {
    if(output["deeply"]["nested"]) {
      if(output["deeply"]["nested"]["array"]) {
        if(output["deeply"]["nested"]["array"].indexOf("conditionB") !== -1) {
          return;
        }
      }
    }
  }
} 
console.error("There is an error somewhere you need to be fixing.");
return;

If you'd like something that's a little easier to use and understand, try something like this. 如果您想要一些更容易使用和理解的东西,请尝试这样的事情。 Season to taste. 品尝季节。

function getStructValue( object, propertyExpression, defaultValue ) {
    var temp = object;
    var propertyList = propertyExpression.split(".");
    var isMatch = false;
    for( var i=0; i<propertyList.length; ++i ) {
        var value = temp[ propertyList[i] ];
        if( value ) {
            temp = value;
            isMatch = true;
        }
        else {
            isMatch = false;
        }
    }
    if( isMatch ) {
        return temp;
    }
    else {
        return defaultValue;
    }
}

Here's some tests: 这是一些测试:

var testData = {
    apples : {
        red: 3,
        green: 9,
        blue: {
            error: "there are no blue apples"
        }
    }
};

console.log( getStructValue( testData, "apples.red", "No results" ) );
console.log( getStructValue( testData, "apples.blue.error", "No results" ) );
console.log( getStructValue( testData, "apples.blue.error.fail", "No results" ) );
console.log( getStructValue( testData, "apples.blue.moon", "No results" ) );
console.log( getStructValue( testData, "orange.you.glad", "No results" ) );

And the output from the tests: 并且测试的输出:

$ node getStructValue.js 
3
there are no blue apples
No results
No results
No results
$ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM