本文翻译自: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 function
在Object.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 }