我有一个目标:

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


当前回答

另一种不同的做法是使用自定义的json字符串函数,该函数也可以处理深层对象。如果您打算将其作为json发布到服务器,这可能很有用

常量obj={‘a’:1,‘b’:2,x:{‘c’:3}}const json=json.stringify(obj,(k,v)=>typeof v==“number”?v*v:v)console.log(json)console.log('返回json:',json.parse(json))

其他回答

我在谷歌搜索中发现了这一点,这是我试图学习如何做到这一点的第一个项目,我想我会与其他folsk分享我最近发现的解决方案,它使用了npm包不可变。

我觉得分享很有趣,因为不可变在他们自己的文档中使用了OP的EXACT情况——以下不是我自己的代码,而是从当前不可变的js文档中提取的:

const { Seq } = require('immutable')
const myObject = { a: 1, b: 2, c: 3 }
Seq(myObject).map(x => x * x).toObject();
// { a: 1, b: 4, c: 9 } 

这并不是说Seq有其他财产(“Seq描述了一个惰性操作,允许它们通过不创建中间集合来高效地链接所有高阶集合方法(如map和filter)的使用”),也不是说其他一些不可变js数据结构也可以非常有效地完成这项工作。

任何使用此方法的人都必须npm安装不可变,并且可能需要阅读文档:

https://facebook.github.io/immutable-js/

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

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

常量orig={“a”:1,“b”:2,“c”:3}常量结果=_.变换(orig,(r,v,k)=>r[k.trim()]=v*2);console.log(结果);<script src=“https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js“></script>

使用new_.transform()转换对象。

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

编辑:使用较新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的全部潜力,但我分享这个答案,因为看到它可以应用到多少地方很有趣。如果您对它的派生方式和其他有用的方式感兴趣,请查看此答案。