我有一个目标:

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功能的规范方法是-

const identity = x =>
  x

const omap = (f = identity, o = {}) =>
  Object.fromEntries(
    Object.entries(o).map(([ k, v ]) =>
      [ k, f(v) ]
    )
  )

其中o是某个对象,f是映射函数。或者我们可以说,给定一个a->b的函数和一个值为a的对象,生成一个值类型为b的对象。作为伪类型签名-

// omap : (a -> b, { a }) -> { b }

最初的答案是为了演示一个强大的组合子mapReduce,它允许我们以不同的方式思考我们的转换

m、 映射函数–让您有机会在…r、 reduce函数–此函数将累加器与映射元素的结果组合

直观地说,mapReduce创建了一个新的reduce,我们可以直接插入Array.prototype.reduce中。但更重要的是,我们可以通过使用对象幺半群、object.assign和{}来简单地实现我们的对象函子实现omap。

常量标识=x=>x(x)常量mapReduce=(m,r)=>(a,x)=>r(a,m(x))常量omap=(f=身份,o={})=>对象.键(o)减少(mapReduce(k=>({[k]:f(o[k])}),对象分配), {})常量平方=x=>x×x常量数据={a:1,b:2,c:3}console.log(omap(方形,数据))//{a:1,b:4,c:9}

请注意,我们实际需要编写的程序的唯一部分是映射实现本身——

k => ({ [k]: f (o[k]) })

也就是说,给定已知对象o和某个键k,构造一个对象,其计算属性k是对键的值o[k]调用f的结果。

如果我们首先抽象oreduce,我们就可以一窥mapReduce的测序潜力

// oreduce : (string * a -> string * b, b, { a }) -> { b }
const oreduce = (f = identity, r = null, o = {}) =>
  Object
    .keys (o)
    .reduce
      ( mapReduce
          ( k => [ k, o[k] ]
          , f
          )
      , r
      )

// omap : (a -> b, {a}) -> {b}
const omap = (f = identity, o = {}) =>
  oreduce
    ( mapReduce
        ( ([ k, v ]) =>
            ({ [k]: f (v) })
        , Object.assign
        )
    , {}
    , o
    )

一切都是一样的,但现在可以在更高级别上定义omap。当然,新的Object.entries让这看起来很愚蠢,但练习对学习者来说仍然很重要。

你不会在这里看到mapReduce的全部潜力,但我分享这个答案,因为看到它可以应用到多少地方很有趣。如果您对它的派生方式和其他有用的方式感兴趣,请查看此答案。

其他回答

最小版本

2017年

Object.entries(obj).reduce((a, [k, v]) => (a[k] = v * v, a), {})
                                                  ↑↑↑↑↑

ES2019年

Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v * v]))
                                                           ↑↑↑↑↑

映射函数在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;
});

为了更准确地响应OP的要求,OP需要一个对象:

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

要使用映射方法myObject.map,

类似于Array.prototype.map,使用如下:newObject=myObject.map(函数(值,标签){返回值*值;});//newObject现在是{“a”:1,“b”:4,“c”:9}

imho最佳答案(以“接近要求的内容”+“不需要ES{5,6,7}”来衡量)是:

myObject.map = function mapForObject(callback)
{
  var result = {};
  for(var property in this){
    if(this.hasOwnProperty(property) && property != "map"){
      result[property] = callback(this[property],property,this);
    }
  }
  return result;
}

上面的代码避免故意使用任何语言特性,这些特性仅在最近的ECMAScript版本中可用。使用上面的代码,问题可以通过以下方式解决:

myObject={“a”:1,“b”:2,“c”:3};myObject.map=函数mapForObject(回调){var结果={};for(此中的var属性){如果(this.hasOwnProperty(property)&&property!=“地图”){result[property]=回调(this[property],property,this);}}返回结果;}newObject=myObject.map(函数(值,标签){返回值*值;});console.log(“newObject is now”,newObject);此处为备选测试代码

除了受到一些人的反对外,还可以像这样将解决方案插入到原型链中。

Object.prototype.map = function(callback)
{
  var result = {};
  for(var property in this){
    if(this.hasOwnProperty(property)){
      result[property] = callback(this[property],property,this);
    }
  }
  return result;
}

在仔细监督的情况下进行的操作不会产生任何不良影响,也不会影响其他对象的贴图方法(即阵列的贴图)。

编辑:使用较新JavaScript功能的规范方法是-

const identity = x =>
  x

const omap = (f = identity, o = {}) =>
  Object.fromEntries(
    Object.entries(o).map(([ k, v ]) =>
      [ k, f(v) ]
    )
  )

其中o是某个对象,f是映射函数。或者我们可以说,给定一个a->b的函数和一个值为a的对象,生成一个值类型为b的对象。作为伪类型签名-

// omap : (a -> b, { a }) -> { b }

最初的答案是为了演示一个强大的组合子mapReduce,它允许我们以不同的方式思考我们的转换

m、 映射函数–让您有机会在…r、 reduce函数–此函数将累加器与映射元素的结果组合

直观地说,mapReduce创建了一个新的reduce,我们可以直接插入Array.prototype.reduce中。但更重要的是,我们可以通过使用对象幺半群、object.assign和{}来简单地实现我们的对象函子实现omap。

常量标识=x=>x(x)常量mapReduce=(m,r)=>(a,x)=>r(a,m(x))常量omap=(f=身份,o={})=>对象.键(o)减少(mapReduce(k=>({[k]:f(o[k])}),对象分配), {})常量平方=x=>x×x常量数据={a:1,b:2,c:3}console.log(omap(方形,数据))//{a:1,b:4,c:9}

请注意,我们实际需要编写的程序的唯一部分是映射实现本身——

k => ({ [k]: f (o[k]) })

也就是说,给定已知对象o和某个键k,构造一个对象,其计算属性k是对键的值o[k]调用f的结果。

如果我们首先抽象oreduce,我们就可以一窥mapReduce的测序潜力

// oreduce : (string * a -> string * b, b, { a }) -> { b }
const oreduce = (f = identity, r = null, o = {}) =>
  Object
    .keys (o)
    .reduce
      ( mapReduce
          ( k => [ k, o[k] ]
          , f
          )
      , r
      )

// omap : (a -> b, {a}) -> {b}
const omap = (f = identity, o = {}) =>
  oreduce
    ( mapReduce
        ( ([ k, v ]) =>
            ({ [k]: f (v) })
        , Object.assign
        )
    , {}
    , o
    )

一切都是一样的,但现在可以在更高级别上定义omap。当然,新的Object.entries让这看起来很愚蠢,但练习对学习者来说仍然很重要。

你不会在这里看到mapReduce的全部潜力,但我分享这个答案,因为看到它可以应用到多少地方很有趣。如果您对它的派生方式和其他有用的方式感兴趣,请查看此答案。

根据@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}