Deeply changing values ​​in a JavaScript object

I have an object that contains an unknown number of other objects. Each (sub) object can contain boolean values ​​as strings and I want to change them to real boolean values. Here's an example of an object:

var myObj = {
  my1stLevelKey1: "true",
  my1stLevelKey2: "a normal string",
  my1stLevelKey3: {
    my2ndLevelKey1: {
      my3rdLevelKey1: {
        my4thLevelKey1: "true",
        my4thLevelKey2: "false"
      }
    },
    my2ndLevelKey2: {
      my3rdLevelKey2: "FALSE"
    }
  }
}

      

In the end I want:

var myObj = {
  my1stLevelKey1: true,
  my1stLevelKey2: "a normal string",
  my1stLevelKey3: {
    my2ndLevelKey1: {
      my3rdLevelKey1: {
        my4thLevelKey1: true,
        my4thLevelKey2: false
      }
    },
    my2ndLevelKey2: {
      my3rdLevelKey2: false
    }
  }
}

      

It is important that the number of sub-objects / levels of the number is unknown. How can I do this efficiently using classic JavaScript or Mootools?

+3


source to share


4 answers


Recursion is your friend

(function (obj) { // IIFE so you don't pollute your namespace
    // define things you can share to save memory
    var map = Object.create(null);
    map['true'] = true;
    map['false'] = false;
    // the recursive iterator
    function walker(obj) {
        var k,
            has = Object.prototype.hasOwnProperty.bind(obj);
        for (k in obj) if (has(k)) {
            switch (typeof obj[k]) {
                case 'object':
                    walker(obj[k]); break;
                case 'string':
                    if (obj[k].toLowerCase() in map) obj[k] = map[obj[k].toLowerCase()]
            }
        }
    }
    // set it running
    walker(obj);
}(myObj));

      



obj[k].toLowerCase()

is to make it case insensitive

+13


source


Go through each level of the object and replace the boolean string values ​​with the corresponding booleans. If you find an object, repeat the procedure and replace it again.

You can use Object.keys

to grab all members of each object without worrying about getting inherited properties that you don't need.



var myObj = {
  my1stLevelKey1: "true",
  my1stLevelKey2: "a normal string",
  my1stLevelKey3: {
    my2ndLevelKey1: {
      my3rdLevelKey1: {
        my4thLevelKey1: "true",
        my4thLevelKey2: "false"
      }
    },
    my2ndLevelKey2: {
      my3rdLevelKey2: "FALSE"
    }
  }
};

function booleanizeObject(obj) {
  var keys = Object.keys(obj);
  keys.forEach(function(key) {
    var value = obj[key];
    if (typeof value === 'string') {
      var lvalue = value.toLowerCase();
      if (lvalue === 'true') {
        obj[key] = true;
      } else if (lvalue === 'false') {
        obj[key] = false;
      }
    } else if (typeof value === 'object') {
      booleanizeObject(obj[key]);
    }
  });
}

booleanizeObject(myObj);

document.getElementById('results').textContent = JSON.stringify(myObj);
      

<pre id="results"></pre>
      

Run codeHide result


0


source


JavaScript data structures can be elegantly sanitized with recursive functional approaches reduce

.

var myObj = {
  my1stLevelKey1: "true",
  my1stLevelKey2: "a normal string",
  my1stLevelKey3: {
    my2ndLevelKey1: {
      my3rdLevelKey1: {
        my4thLevelKey1: "true",
        my4thLevelKey2: "false"
      }
    },
    my2ndLevelKey2: {
      my3rdLevelKey2: "FALSE"
    }
  }
};


myObj = Object.keys(myObj).reduce(function sanitizeBooleanStructureRecursively (collector, key) {
  var
    source  = collector.source,
    target  = collector.target,

    value   = source[key],

    str
  ;
  if (value && (typeof value == "object")) {

    value = Object.keys(value).reduce(sanitizeBooleanStructureRecursively, {

      source: value,
      target: {}

    }).target;

  } else if (typeof value == "string") {

    str   = value.toLowerCase();
    value = ((str == "true") && true) || ((str == "false") ? false : value)
  }
  target[key] = value;

  return collector;

}, {

  source: myObj,
  target: {}

}).target;


console.log(myObj);

      

0


source


An example of simple javascript recursion:

function mapDeep( obj ) {
    for ( var prop in obj ) {
        if ( obj[prop] === Object(obj[prop]) ) mapDeep( obj[prop] );
        else if ( obj[prop].toLowerCase() === 'false' ) obj[prop] = false;
        else if ( obj[prop].toLowerCase() === 'true' ) obj[prop] = true;
    }                   
};

      

And a MooTools example, expanding the type Object

with a custom function mapDeep()

:

Object.extend( 'mapDeep', function( obj, custom ) {
    return Object.map( obj, function( value, key ) {
        if ( value === Object( value ) )
            return Object.mapDeep( value, custom );
        else
            return custom( value, key );                    
    });
});


myObj = Object.mapDeep( myObj, function( value, key ) {
    var bool = { 'true': true, 'false': false };        
    return value.toLowerCase() in bool ? bool[ value.toLowerCase() ] : value;           
}) 

      

0


source







All Articles