对象的映射功能(而不是数组)

本文翻译自:map function for objects (instead of arrays)

I have an object: 我有一个对象:

myObject = { 'a': 1, 'b': 2, 'c': 3 }

I am looking for a native method, similar to Array.prototype.map that would be used as follows: 我正在寻找类似于Array.prototype.map的本机方法,该方法将按以下方式使用:

newObject = myObject.map(function (value, label) {
    return value * value;
});

// newObject is now { 'a': 1, 'b': 4, 'c': 9 }

Does JavaScript have such a map function for objects? JavaScript是否为对象提供了这种map功能? (I want this for Node.JS, so I don't care about cross-browser issues.) (我想为Node.JS使用它,所以我不在乎跨浏览器的问题。)


#1楼

参考:https://stackoom.com/question/108t8/对象的映射功能-而不是数组


#2楼

The map function does not exist on the Object.prototype however you can emulate it like so map functionObject.prototype上不存在,但是您可以像这样模拟它

var myMap = function ( obj, callback ) {

    var result = {};

    for ( var key in obj ) {
        if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
            if ( typeof callback === 'function' ) {
                result[ key ] = callback.call( obj, obj[ key ], key, obj );
            }
        }
    }

    return result;

};

var myObject = { 'a': 1, 'b': 2, 'c': 3 };

var newObject = myMap( myObject, function ( value, key ) {
    return value * value;
});

#3楼

It's pretty easy to write one: 编写一个很简单:

Object.map = function(o, f, ctx) {
    ctx = ctx || this;
    var result = {};
    Object.keys(o).forEach(function(k) {
        result[k] = f.call(ctx, o[k], k, o); 
    });
    return result;
}

with example code: 带有示例代码:

> o = { a: 1, b: 2, c: 3 };
> r = Object.map(o, function(v, k, o) {
     return v * v;
  });
> r
{ a : 1, b: 4, c: 9 }

NB: this version also allows you to (optionally) set the this context for the callback, just like the Array method. 注意:此版本还允许您(可选)设置回调的this上下文,就像Array方法一样。

EDIT - changed to remove use of Object.prototype , to ensure that it doesn't clash with any existing property named map on the object. 编辑 -更改为删除对Object.prototype使用,以确保它不与该对象上任何现有的名为map属性发生冲突。


#4楼

There is no native map to the Object object, but how about this: 没有到Object对象的本地map ,但是如何处理:

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; Object.keys(myObject).map(function(key, index) { myObject[key] *= 2; }); console.log(myObject); // => { 'a': 2, 'b': 4, 'c': 6 } 

But you could easily iterate over an object using for ... in : 但是您可以使用for ... in以下对象中轻松迭代对象:

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; for (var key in myObject) { if (myObject.hasOwnProperty(key)) { myObject[key] *= 2; } } console.log(myObject); // { 'a': 2, 'b': 4, 'c': 6 } 

Update 更新资料

A lot of people are mentioning that the previous methods do not return a new object, but rather operate on the object itself. 很多人提到,以前的方法不会返回新对象,而是对对象本身进行操作。 For that matter I wanted to add another solution that returns a new object and leaves the original object as it is: 为此,我想添加另一个解决方案,该解决方案返回一个新对象并保留原始对象不变:

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; // returns a new object with the values at each key mapped using mapFn(value) function objectMap(object, mapFn) { return Object.keys(object).reduce(function(result, key) { result[key] = mapFn(object[key]) return result }, {}) } var newObject = objectMap(myObject, function(value) { return value * 2 }) console.log(newObject); // => { 'a': 2, 'b': 4, 'c': 6 } console.log(myObject); // => { 'a': 1, 'b': 2, 'c': 3 } 

Array.prototype.reduce reduces an array to a single value by somewhat merging the previous value with the current. Array.prototype.reduce通过将先前值与当前值进行某种程度的合并,将数组减少为单个值。 The chain is initialized by an empty object {} . 该链由一个空对象{}初始化。 On every iteration a new key of myObject is added with twice the key as the value. 每次迭代时,都会添加myObject的新键,并将键的值加倍。

Update 更新资料

With new ES6 features, there is a more elegant way to express objectMap . 借助ES6的新功能,有一种更优雅的方式来表达objectMap

 const objectMap = (obj, fn) => Object.fromEntries( Object.entries(obj).map( ([k, v], i) => [k, fn(v, k, i)] ) ) const myObject = { a: 1, b: 2, c: 3 } console.log(objectMap(myObject, v => 2 * v)) 


#5楼

You could use Object.keys and then forEach over the returned array of keys: 您可以使用Object.keys然后在返回的键数组上使用forEach

var myObject = { 'a': 1, 'b': 2, 'c': 3 },
    newObject = {};
Object.keys(myObject).forEach(function (key) {
    var value = myObject[key];
    newObject[key] = value * value;
});

Or in a more modular fashion: 或更模块化的方式:

function map(obj, callback) {
    var result = {};
    Object.keys(obj).forEach(function (key) {
        result[key] = callback.call(obj, obj[key], key, obj);
    });
    return result;
}

newObject = map(myObject, function(x) { return x * x; });

Note that Object.keys returns an array containing only the object's own enumerable properties, thus it behaves like a for..in loop with a hasOwnProperty check. 请注意, Object.keys返回一个仅包含对象自己的可枚举属性的数组,因此它的行为类似于带有hasOwnProperty检查的for..in循环。


#6楼

No native methods, but lodash#mapValues will do the job brilliantly 没有本机方法,但是lodash#mapValues可以出色地完成这项工作

_.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
// → { 'a': 3, 'b': 6, 'c': 9 }
发布了0 篇原创文章 · 获赞 73 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/105340527