我有一个目标:
myObject = { 'a': 1, 'b': 2, 'c': 3 }
我正在寻找一个本地方法,类似于Array.prototype.map,可按如下方式使用:
newObject = myObject.map(function (value, label) {
return value * value;
});
// newObject is now { 'a': 1, 'b': 4, 'c': 9 }
JavaScript是否有这样的对象映射函数?(我希望Node.JS使用这个,所以我不关心跨浏览器问题。)
JavaScript刚刚获得了新的Object.fromEntries方法。
实例
函数mapObject(obj,fn){返回Object.fromEntries(对象.entries(对象).map(fn))}常量myObject={a:1,b:2,c:3}const myNewObject=mapObject(myObject,([key,value])=>([key、value*value]))console.log(myNewObject)
解释
上面的代码将Object转换为可以映射的嵌套数组([[<key>,<value>],…])。Object.fromEntries将数组转换回对象。
这种模式最酷的一点是,现在可以在映射时轻松地考虑对象关键点。
文档
对象.fromEntries()Object.entries()
浏览器支持
Object.fromEntries目前仅受这些浏览器/引擎支持,但仍有polyfill可用(例如@babel/polyfill)。
映射函数在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;
});
const mapObject = (targetObject, callbackFn) => {
if (!targetObject) return targetObject;
if (Array.isArray(targetObject)){
return targetObject.map((v)=>mapObject(v, callbackFn))
}
return Object.entries(targetObject).reduce((acc,[key, value]) => {
const res = callbackFn(key, value);
if (!Array.isArray(res) && typeof res ==='object'){
return {...acc, [key]: mapObject(res, callbackFn)}
}
if (Array.isArray(res)){
return {...acc, [key]: res.map((v)=>mapObject(v, callbackFn))}
}
return {...acc, [key]: res};
},{})
};
const mapped = mapObject(a,(key,value)=> {
if (!Array.isArray(value) && key === 'a') return ;
if (!Array.isArray(value) && key === 'e') return [];
if (!Array.isArray(value) && key === 'g') return value * value;
return value;
});
console.log(JSON.stringify(mapped));
// {"b":2,"c":[{"d":2,"e":[],"f":[{"g":4}]}]}
此函数递归地遍历对象和对象数组。如果返回未定义,则可以删除属性
写一个很简单:
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;
}
示例代码:
> 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 }
注意:这个版本还允许您(可选)为回调设置this上下文,就像Array方法一样。
EDIT-更改为删除Object.prototype的使用,以确保它不会与对象上任何现有的名为map的属性冲突。