我有一个目标:

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使用这个,所以我不关心跨浏览器问题。)


当前回答

没有到Object对象的本机映射,但这如何:

var myObject={“a”:1,“b”:2,“c”:3};Object.keys(myObject).forEach(函数(键,索引){myObject[key]*=2;});console.log(myObject);//=>{“a”:2,“b”:4,“c”:6}

但是您可以使用for。。。在:

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

使现代化

很多人都提到,以前的方法不会返回新对象,而是对对象本身进行操作。为此,我想添加另一个解决方案,该方案返回一个新对象并保持原始对象的原样:

var myObject={“a”:1,“b”:2,“c”:3};//返回一个新对象,其中每个键的值都使用mapFn(value)映射函数objectMap(对象,mapFn){return Object.keys(Object).reduce(function(result,key){result[key]=mapFn(对象[key])返回结果}, {})}var newObject=对象映射(myObject,函数(值){返回值*2})console.log(newObject);//=>{“a”:2,“b”:4,“c”:6}console.log(myObject);//=>{“a”:1,“b”:2,“c”:3}

Array.prototype.reduce通过将前一个值与当前值进行某种程度的合并,将数组缩减为单个值。链由空对象{}初始化。每次迭代时,都会添加myObject的一个新键,该键的值是该键的两倍。

使现代化

有了新的ES6特性,有了一种更优雅的方式来表达objectMap。

常量对象映射=(obj,fn)=>对象.fromEntries(对象条目(obj).map(([k,v],i)=>[k,fn(v,k,i)]))常量myObject={a:1,b:2,c:3}console.log(objectMap(myObject,v=>2*v))

其他回答

Async,有人吗?

尽管有大量的评论,但我没有找到使用异步映射器的解决方案。这是我的。

使用p-map,一个受信任的(@sindresorhus)和小的依赖关系。

(注意,没有选项传递给p-map。如果需要调整并发/错误处理,请参阅文档)。

字体:

import pMap from "p-map";

export const objectMapAsync = async <InputType, ResultType>(
  object: { [s: string]: InputType } | ArrayLike<InputType>,
  mapper: (input: InputType, key: string, index: number) => Promise<ResultType>
): Promise<{
  [k: string]: ResultType;
}> => {
  const mappedTuples = await pMap(
    Object.entries(object),
    async ([key, value], index) => {
      const result = await mapper(value, key, index);
      return [key, result];
    }
  );

  return Object.fromEntries(mappedTuples);
};

普通JS:

import pMap from "p-map";

export const objectMapAsync = async (
  object,
  mapper
) => {
  const mappedTuples = await pMap(
    Object.entries(object),
    async ([key, value], index) => {
      const result = await mapper(value, key, index);
      return [key, result];
    }
  );

  return Object.fromEntries(mappedTuples);
};

};

用法示例:

(精心设计,无错误处理,无类型)

// Our object in question.
const ourFavouriteCharacters = {
  me: "luke",
  you: "vader",
  everyone: "chewbacca",
};

// An async function operating on the object's values (in this case, strings)
const fetchCharacter = (charName) =>
  fetch(`https://swapi.dev/api/people?search=${charName}`)
    .then((res) => res.json())
    .then((res) => res.results[0]);

// `objectMapAsync` will return the final mapped object to us
//  (wrapped in a Promise)
objectMapAsync(ourFavouriteCharacters, fetchCharacter).then((res) =>
  console.log(res)
);

根据@Amberlamps的回答,这里有一个实用函数(作为评论,它看起来很难看)

function mapObject(obj, mapFunc){
    return Object.keys(obj).reduce(function(newObj, value) {
        newObj[value] = mapFunc(obj[value]);
        return newObj;
    }, {});
}

其用途是:

var obj = {a:1, b:3, c:5}
function double(x){return x * 2}

var newObj = mapObject(obj, double);
//=>  {a: 2, b: 6, c: 10}

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' ]

没有原生方法,但lodash#mapValues将出色地完成这项工作

_.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
// → { 'a': 3, 'b': 6, 'c': 9 }

我需要一个允许修改密钥的版本(基于@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"}
}

编辑:对传入起始对象{}进行轻微更改。允许为[](如果键是整数)