JavaScript对象中深层次更改的值

时间:2021-06-13 22:04:36

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有效地做到这一点?

4 个解决方案

#1


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()是为了使它不区分大小写

#2


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>

#3


JavaScript data structures elegantly can be sanitized by recursive functional reduce approaches.

优雅的JavaScript数据结构可以通过递归功能减少方法进行清理。

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

#4


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

#1


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()是为了使它不区分大小写

#2


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>

#3


JavaScript data structures elegantly can be sanitized by recursive functional reduce approaches.

优雅的JavaScript数据结构可以通过递归功能减少方法进行清理。

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

#4


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