Javascript is equivalent to python dictionary.get

I am trying to validate a JSON object using node.js. Basically, if condition A is present, I want to make sure that the particular value is in the array, which may be missing. I am doing this in python using dictionary.get because that will return the default if I find something that is not there. This is what python looks like

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 would like to find a similar technique for javascript. I tried to use the defaults in the underscore to create keys if there are none, but I don't think I did it right, or I am 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 that if it works with an output where one of the nested objects is missing, it doesn't replace it with the default and instead removes TypeError: Cannot read property 'variety' of undefined

where "sort" is the name of the array I'm looking at.

+3


source to share


4 answers


Or better yet, here's a quick wrapper that mimics the functionality of a python dictionary.

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 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.

+4


source


The standard technique for doing this in JS (since your expected objects are all true) is using the operator ||

for the defaults:

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 usage _.defaults

is that it is not recursive - it doesn't work on deeply nested objects.

+1


source


You can check that the key exists in javascript by accessing it.

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;

      

0


source


If you want something 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 are 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 test result:

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

      

0


source







All Articles