我有一个目标:
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使用这个,所以我不关心跨浏览器问题。)
TypeScript中的对象映射器
我喜欢像这样使用Object.fromEntries的示例,但它们仍然不太好用。使用Object.keys然后查找关键字的答案实际上是在进行可能不需要的多次查找。
我希望有一个Object.map函数,但我们可以创建自己的函数,并将其称为objectMap,同时可以修改键和值:
用法(JavaScript):
const myObject = { 'a': 1, 'b': 2, 'c': 3 };
// keep the key and modify the value
let obj = objectMap(myObject, val => val * 2);
// obj = { a: 2, b: 4, c: 6 }
// modify both key and value
obj = objectMap(myObject,
val => val * 2 + '',
key => (key + key).toUpperCase());
// obj = { AA: '2', BB: '4', CC: '6' }
代码(TypeScript):
interface Dictionary<T> {
[key: string]: T;
}
function objectMap<TValue, TResult>(
obj: Dictionary<TValue>,
valSelector: (val: TValue, obj: Dictionary<TValue>) => TResult,
keySelector?: (key: string, obj: Dictionary<TValue>) => string,
ctx?: Dictionary<TValue>
) {
const ret = {} as Dictionary<TResult>;
for (const key of Object.keys(obj)) {
const retKey = keySelector
? keySelector.call(ctx || null, key, obj)
: key;
const retVal = valSelector.call(ctx || null, obj[key], obj);
ret[retKey] = retVal;
}
return ret;
}
如果您没有使用TypeScript,请在TypeScript Playground中复制上述代码以获取JavaScript代码。
此外,我在参数列表中将keySelector放在valSelector之后的原因是它是可选的。
*亚历山大·米尔斯的回答值得称赞。
我需要一个允许修改密钥的版本(基于@Amberlamps和@yonatanmn答案);
var facts = [ // can be an object or array - see jsfiddle below
{uuid:"asdfasdf",color:"red"},
{uuid:"sdfgsdfg",color:"green"},
{uuid:"dfghdfgh",color:"blue"}
];
var factObject = mapObject({}, facts, function(key, item) {
return [item.uuid, {test:item.color, oldKey:key}];
});
function mapObject(empty, obj, mapFunc){
return Object.keys(obj).reduce(function(newObj, key) {
var kvPair = mapFunc(key, obj[key]);
newObj[kvPair[0]] = kvPair[1];
return newObj;
}, empty);
}
factObject(事实对象)=
{
"asdfasdf": {"color":"red","oldKey":"0"},
"sdfgsdfg": {"color":"green","oldKey":"1"},
"dfghdfgh": {"color":"blue","oldKey":"2"}
}
编辑:对传入起始对象{}进行轻微更改。允许为[](如果键是整数)
ES6:
Object.prototype.map = function(mapFunc) {
return Object.keys(this).map((key, index) => mapFunc(key, this[key], index));
}
2015年:
Object.prototype.map = function (mapFunc) {
var _this = this;
return Object.keys(this).map(function (key, index) {
return mapFunc(key, _this[key], index);
});
};
节点中的测试:
> a = {foo: "bar"}
{ foo: 'bar' }
> a.map((k,v,i) => v)
[ 'bar' ]
您可以在返回的键数组上使用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;
});
或者以更模块化的方式:
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; });
请注意,Object.keys返回的数组只包含对象自己的可枚举财产,因此其行为类似于for。。在循环中使用hasOwnProperty检查。