我有一个对象:
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是否具有对象的 map
函数? (我想将它用于Node.JS,所以我不关心跨浏览器问题 . )
25 回答
嘿写了一个可能有帮助的小映射器功能 .
您可以在返回的键数组上使用Object.keys然后
forEach
:或者以更模块化的方式:
请注意,
Object.keys
返回一个仅包含对象自己的可枚举属性的数组,因此它的行为类似于带有hasOwnProperty
检查的for..in
循环 .这是直接的bs,JS社区中的每个人都知道它 . 应该有这个功能:
这是天真的实现:
必须始终自己实现这一点非常烦人;)
如果你想要一些更复杂的东西,这不会干扰Object类,试试这个:
但是将这个map函数添加到Object是安全的,只是不要添加到Object.prototype .
基于@Amberlamps答案,这里是一个实用功能(作为评论看起来很难看)
用途是:
另一种观点是使用自定义json stringify函数,该函数也可以在深层对象上运行 . 如果您打算将其作为json发布到服务器,这可能很有用
我来到这里寻找并回答将对象映射到数组并获得此页面的结果 . 如果你来到这里寻找我的答案,这里是你如何映射和对象的数组 .
您可以使用map从对象返回一个新数组,如下所示:
这个答案已被重写,以展示一个强大的组合,
mapReduce
,它允许我们以不同的方式思考我们的转变m
,映射函数 - 让您有机会在传入元素之前转换...r
,reduce函数 - 此函数将累加器与映射元素的结果组合在一起直观地说,
mapReduce
创建了一个新的减速器,我们可以直接插入Array.prototype.reduce
. 但更重要的是,我们可以通过利用对象monoid,Object.assign
和{}
来实现我们的对象仿函数实现omap
.请注意,我们实际必须编写的程序的唯一部分是映射实现本身 -
其中,给定一个已知对象
o
和一些键k
,构造一个对象,其属性k
是在键的值o [k]
上调用f
的结果 .如果我们第一次抽象
oreduce
,我们可以看到mapReduce
的测序潜力一切都是一样的,但现在可以在更高级别定义
omap
. 当然新的Object.entries
让这看起来很傻,但练习对学习者来说仍然很重要 .你不会在这里看到
mapReduce
的全部潜力,但我分享了这个答案,因为's interesting to see just how many places it can be applied. If you'对它的衍生方式以及它可能有用的其他方式感兴趣,请参阅this answer .如果有人在寻找将对象映射到新对象或数组的简单解决方案:
这可能不适用于所有对象或所有映射函数,但它适用于简单的浅层对象和直接的映射函数,这是我所需要的 .
最小版本(es6):
如果你对
map
不仅对值而且对键都感兴趣,我写了Object.map(valueMapper, keyMapper),其行为方式如下:我特别想使用我用于单个对象的数组的相同功能,并希望保持简单 . 这对我有用:
为了获得最佳性能
如果您的对象不经常更改但需要经常迭代,我建议使用本机Map作为缓存 .
Object.entries已经可以在Chrome,Edge,Firefox和beta Opera中使用,所以它来自ES7,因此它可以填充它https://github.com/es-shims/Object.entries,因为IE无效 .
您可以在数组上使用
map
方法和forEach
,但如果您想在Object
上使用它,那么您可以像下面一样使用它:Using Javascript (ES6)
Using jQuery
或者您可以使用其他循环,如
$.each
方法,如下例所示:我发现这是谷歌搜索中的第一项,试图学习如何做到这一点,并认为我会分享其他folsk最近发现我找到的解决方案,它使用npm包不可变 .
我觉得分享很有意思,因为不可变在他们自己的文档中使用了OP的精确情况 - 以下不是我自己的代码,而是从当前的immutable-js文档中提取的:
并不是说Seq有其他属性(“Seq描述了一个惰性操作,允许它们有效地链接使用所有高阶集合方法(例如map和通过不创建中间集合“)和其他一些不可变的js数据结构也可以非常有效地完成工作 .
使用此方法的任何人当然都必须
npm install immutable
并且可能想要阅读文档:https://facebook.github.io/immutable-js/
接受的答案有两个缺点:
它误用
Array.prototype.reduce
,因为减少意味着改变复合类型的结构,在这种情况下不会发生 .它不是特别可重复使用的
ES6 / ES2015功能方法
请注意,所有功能都以咖喱形式定义 .
在A行
o
被重新分配 . 由于Javascript传递参考值by sharing,因此会生成o
的浅表副本 . 我们现在能够在omap
内变异o
,而不会在父作用域中改变o
.在行B中
map
的返回值被忽略,因为map
执行了o
的变异 . 由于此副作用仍在omap
范围内,并且在父范围内不可见,因此完全可以接受 .这不是最快的解决方案,而是一个声明性和可重用的解决方案 . 这里的实现与单行,简洁但不太可读相同:
附录 - 为什么默认情况下对象不可迭代?
ES2015指定了迭代器和可迭代协议 . 但是对象仍然不可迭代,因此无法映射 . The reason is the mixing of data and program level .
没有本地方法,但lodash#mapValues将完美地完成这项工作
如何在普通JS( ES6 / ES2015 )中使用立即变量赋值的单行程怎么样?
使用spread operator和computed key name语法:
jsbin
使用reduce的另一个版本:
jsbin
作为函数的第一个例子:
jsbin
如果要以函数样式映射嵌套对象 recursively ,可以这样做:
jsbin
或者更重要的是,像这样:
jsbin
自 ES7 / ES2016 起,您可以使用Object.entries而不是
Object.keys
,例如像这样:继承属性和原型链:
在极少数情况下,您可能需要映射类似于对象的对象,该对象在其prototype-chain上包含继承对象的属性 . 在这种情况下
Object.keys()
将无法工作,因为Object.keys()
不会枚举继承的属性 . 如果需要映射继承的属性,则应使用for (key in myObj) {...}
.下面是一个继承另一个对象属性的对象示例,以及
Object.keys()
在这种情况下不起作用 .jsbin
但是,请帮我一个忙,避免继承 . :-)
map function
上不存在map function
但是你可以像这样模仿它您可以通过有序对使用简单的for-in循环 . 我使用了
hasOwnProperty()
,因为您为对象创建了三个属性(带有值) . 第一种方法不会创建 Map . 相反,它只是将函数应用于单个元素,这可以在很多情况下大大加快执行速度 .第二种方法以与第一种方法类似的方式创建 Map ,但可能比这里的其他答案慢得多 .
Object
对象没有原生的map
,但是这个怎么样:但您可以使用
for ... in
轻松迭代对象:Update
很多人都提到前面的方法不返回一个新对象,而是操作对象本身 . 就此而言,我想添加另一个返回新对象的解决方案,并保留原始对象:
Array.prototype.reduce通过稍微将先前值与当前值合并,将数组减少为单个值 . 该链由空对象
{}
初始化 . 在每次迭代中,添加myObject
的新键,其方块为值 .写一个很容易:
使用示例代码:
注意:此版本还允许您(可选)为回调设置
this
上下文,就像Array
方法一样 .EDIT - 已更改为删除
Object.prototype
的使用,以确保它不会与对象上名为map
的任何现有属性冲突 .我需要一个允许修改键的版本(基于@Amberlamps和@yonatanmn答案);
factObject =
编辑:稍微更改以传入起始对象{} . 允许它为[](如果键是整数)
为了更准确地回应OP所要求的内容,OP需要一个对象:
有一个 Map 方法
myObject.map
,最好的imho(以“接近所谓的" + "无ES {5,6,7}不必要地”的答案来衡量)答案是:
上面的代码避免故意使用任何语言功能,仅适用于最新的ECMAScript版本 . 用上面的代码可以解决问题lke:
alternative test code here
除了一些人不喜欢之外,还可以像这样在原型链中插入解决方案 .
有些东西,在仔细监督的情况下完成不应该产生任何不良影响,也不会影响其他对象的方法(即Array的
map
) .使用新的_.transform() to transforms object .