简体   繁体   English

如何深层映射对象

[英]How to MAP an Object Deeply

I want to change somthing in my all values of object let say for example 我想改变我的所有对象值,比如说

var a = {a:{c:1},b:2};
desire output :  a = {a:{c:5},b:10} //multiply by 5

I am doing like this 我就是这样

 var m = function n (o){
    return Object.keys(o).map(function(v,i){
        if(o[v] !== null && typeof o[v] === 'object') return n(o[v])
        else return (o[v]*5);
    })
    }

a = m({a:{c:1},b:2})

But getting output of a 但是得到一个输出

[
  [
    5
  ],
  10
]

To generate one object from another, people will frequently use reduce : 为了从另一个对象生成一个对象,人们将经常使用reduce

 var a = {a: {c: 1}, b: 2}; var m = function n(o) { return Object.keys(o).reduce(function(newObj, key) { var value = o[key]; if (value !== null && typeof value === 'object') { newObj[key] = n(value); } else { newObj[key] = value * 5; } return newObj; }, {}); }; console.log(m(a)); 

We pass in a new object as the "accumulator" and set properties on it, returning it from the reduce callback each time so it passes through the entire process. 我们传入一个新对象作为“累加器”,并为其设置属性,每次都从reduce回调返回它,从而使它遍历整个过程。

This is sometimes called an "abusage" of reduce , since the value of the accumulator never changes (it's always the same object; the object's state changes, but not the object), whereas normally the reduce callback alters the value passing through it. 这有时被称为一个的“abusage” reduce ,由于累加器的不会改变(它总是相同的对象;对象的状态变化,但不是对象),而正常情况下reduce回调改变通过它的值。

If you prefer, forEach closing over the new object is the other common way: 如果您愿意, forEach关闭新对象是另一种常见方法:

 var a = {a: {c: 1}, b: 2}; var m = function n(o) { var newObj = {}; Object.keys(o).forEach(function(key) { var value = o[key]; if (value !== null && typeof value === 'object') { newObj[key] = n(value); } else { newObj[key] = value * 5; } }); return newObj; }; console.log(m(a)); 

You can do it recursively: 您可以递归执行:

var myObj = {a:{c:1},b:2};

function changeChild(obj) {
    var keys = Object.keys(obj);
    keys.forEach(key => {
        if (typeof obj[key] === "object") {
            changeChild(obj[key])
        } else if (typeof obj[key] === "number") {
            obj[key] = obj[key] * 5;
        }
    });
}

changeChild(myObj);

console.log(myObj);

A cleaner way... 更干净的方式...

var m = function (object) {
    for(var key in object) {
        if(!!object[key] && typeof object[key] === 'object') {
            object[key] = m(object[key]);
        } else {
            object[key] *= 5;
        }
    }
    return object;
};

Array.map function returns Array..this is the reason...and if you know what to change inside the object, why won't you do it directly? Array.map函数返回Array ..这就是原因...如果您知道对象内部要更改的内容,为什么不直接这样做呢?

From my point of view you're doing redundant executions for something really simple. 从我的角度来看,您正在为一些非常简单的事情执行冗余执行。

you're creating an anonymous function, using Object.keys to get a new array (after it iterated your object) 您正在创建一个匿名函数,使用Object.keys获取一个新数组(在迭代您的对象之后)

you're using Array.map to create another array from this array and inside it creating ( another ) anonymous function to iterate the new array, and on every iteration you're creating another 4 conditional branches.. 您正在使用Array.map从该数组创建另一个数组,并在其内部创建( 另一个 )匿名函数来迭代新数组,并在每次迭代中创建另外4个条件分支。

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

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