简体   繁体   English

JavaScript对象中深层次更改的值

[英]Deep changing values in a JavaScript object

I have an object which contains an unknown number of other objects. 我有一个包含未知数量的其他对象的对象。 Each (sub-)object may contain boolean values as strings and I want to change them to real boolean values. 每个(子)对象可以包含布尔值作为字符串,我想将它们更改为实际的布尔值。 Here's an example object: 这是一个示例对象:

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

What I want in the end is this: 我最终想要的是:

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

Important is that the number sub-objects/levels is unknown. 重要的是数字子对象/级别是未知的。 How can I do this effectively by either using classic JavaScript or Mootools? 如何使用经典JavaScript或Mootools有效地做到这一点?

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));

The obj[k].toLowerCase() is to make it case-insensitive obj[k].toLowerCase()是为了使它不区分大小写

Walk each level of the object and replace boolean string values with the appropriate booleans. 遍历对象的每个级别,并用适当的布尔值替换布尔字符串值。 If you find an object, recurse in and replace again. 如果找到对象,请重新进入并替换。

You can use Object.keys to grab all the members of each object, without worrying about getting inherited properties that you shouldn't. 您可以使用Object.keys来获取每个对象的所有成员,而不必担心获取不应该继承的属性。

 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> 

JavaScript data structures elegantly can be sanitized by recursive functional reduce approaches. 优雅的JavaScript数据结构可以通过递归功能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);

Plain javascript recursion example: 普通的javascript递归示例:

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 MooTools example, by extending the Object type with custom mapDeep() function: 和MooTools一样,通过使用自定义mapDeep()函数扩展Object类型:

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;           
}) 

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

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