underscore.js
中的map
函数,如果传入一个JavaScript对象,则返回一个由该对象值映射而来的值数组。
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]
有没有一种方法可以使它保留键?也就是说,我想要一个返回结果为
{one: 3, two: 6, three: 9}
underscore.js
中的map
函数,如果传入一个JavaScript对象,则返回一个由该对象值映射而来的值数组。
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]
有没有一种方法可以使它保留键?也就是说,我想要一个返回结果为
{one: 3, two: 6, three: 9}
使用Underscore
Underscore提供了一个函数_.mapObject
,用于映射值并保留键。
_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
使用 Lodash
Lodash 提供了一个名为 _.mapValues
的函数,可以映射值并保留键。
_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
_.map()
иҝ”еӣһзҡ„жҳҜ[['one', 3], ['two', 6], ['three', 9]]
пјҢеҚідёҖдёӘеҢ…еҗ«ж•°з»„зҡ„ж•°з»„пјҢиҖҢ_.object()
еҲҷе°Ҷе…¶иҪ¬жҚўеӣһеҜ№иұЎгҖӮ - Jezen Thomas我在lodash这个类似于underscore的实用库中找到了所需的函数。
http://lodash.com/docs#mapValues
_.mapValues(object, [callback=identity], [thisArg])
通过对object的每个可枚举属性运行回调函数生成一个具有相同键值的对象。 回调函数绑定到thisArg并使用三个参数(value,key,object)调用。
这个纯JS版本怎么样 (ES6 / ES2015)?
let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));
如果您想要对一个对象进行递归映射(映射嵌套对象),可以按如下方式进行:
const mapObjRecursive = (obj) => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') obj[key] = mapObjRecursive(obj[key]);
else obj[key] = obj[key] * 3;
});
return obj;
};
自从 ES7 / ES2016 开始,你可以像这样使用 Object.entries
替代 Object.keys
:
let newObj = Object.assign(...Object.entries(obj).map(([k, v]) => ({[k]: v * 3})));
自从ES2019起,您可以使用Object.fromEntries
方法。
let newObj = Object.fromEntries(Object.entries(obj).map(([k, v]) => ([k, v * 3])))
entries
和 fromEntries
结合起来是一个非常聪明的方法。 - Drenaivar mapped = _.reduce({ one: 1, two: 2, three: 3 }, function(obj, val, key) {
obj[key] = val*3;
return obj;
}, {});
console.log(mapped);
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
我知道这很老了,但是现在Underscore为对象提供了一个新的映射方法:
_.mapObject(object, iteratee, [context])
当然,你可以为数组和对象构建灵活的映射。
_.fmap = function(arrayOrObject, fn, context){
if(this.isArray(arrayOrObject))
return _.map(arrayOrObject, fn, context);
else
return _.mapObject(arrayOrObject, fn, context);
}
mapObject
方法,请考虑使用 lodash 的 mapValues
方法代替。 - Mark Amery我知道已经过了很长时间,但仍然缺少最明显的通过折叠(在js中称为reduce)解决方案,为了完整起见,我将在此留下它:
function mapO(f, o) {
return Object.keys(o).reduce((acc, key) => {
acc[key] = f(o[key])
return acc
}, {})
}
_.map 返回的是一个数组而不是对象。
如果你想要一个对象,最好使用另一个函数,比如 each
; 如果你真的想使用 map 函数,可以这样做:
Object.keys(object).map(function(value, index) {
object[value] *= 3;
})
但是这很令人困惑,当看到map
时,人们会期望得到一个数组作为结果,然后再进行处理。
map
用于改变一个产生数组输出的输入,你可以像@GG所写的那样组合_.object
和_.map
,但这只是一个口味问题。 - Alberto Zaccagni我想你需要一个mapValues函数(用于在对象的值上映射一个函数),这很容易自己实现:
mapValues = function(obj, f) {
var k, result, v;
result = {};
for (k in obj) {
v = obj[k];
result[k] = f(v);
}
return result;
};
const mapObject = (obj = {}, mapper) =>
Object.entries(obj).reduce(
(acc, [key, val]) => ({ ...acc, [key]: mapper(val) }),
{},
);
使用lodash的_.map函数,就像循环一样实现这个功能
var result={};
_.map({one: 1, two: 2, three: 3}, function(num, key){ result[key]=num * 3; });
console.log(result)
//output
{one: 1, two: 2, three: 3}
Reduce函数看起来很聪明,就像上面的答案一样
_.reduce({one: 1, two: 2, three: 3}, function(result, num, key) {
result[key]=num * 3
return result;
}, {});
//output
{one: 1, two: 2, three: 3}