下划线.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}
答案 0 :(得分:210)
使用下划线
Underscore提供了一个函数_.mapObject
来映射值并保留键。
_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
的 DEMO 强>
使用 Lodash
Lodash提供了一个函数_.mapValues
来映射值并保留键。
_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
的 DEMO 强>
答案 1 :(得分:56)
我设法在lodash中找到了所需的功能,这是一个类似于下划线的实用程序库。
http://lodash.com/docs#mapValues
_.mapValues(object, [callback=identity], [thisArg])
使用与生成的对象和值相同的键创建对象 通过回调运行对象的每个自己的可枚举属性。 回调绑定到thisArg并使用三个参数调用; (值,键,对象)。
答案 2 :(得分:19)
var 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>
&#13;
答案 3 :(得分:13)
我知道这是旧的,但现在Underscore有一个新的对象地图:
_.fmap = function(arrayOrObject, fn, context){
if(this.isArray(arrayOrObject))
return _.map(arrayOrObject, fn, context);
else
return _.mapObject(arrayOrObject, fn, context);
}
您当然可以为数组和对象构建灵活的地图
SELECT p.*, (SELECT SUM(t.time_spent) FROM tasks as t WHERE t.project_id = p.id) as project_fulltime FROM projects as p
答案 4 :(得分:9)
这个版本在普通JS( ES6 / ES2015 )中怎么样?
let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));
如果你想要一个对象递归(映射嵌套的obj),可以这样做:
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})));
答案 5 :(得分:3)
_.map返回一个数组,而不是一个Object。
如果你想要一个对象,你最好使用不同的功能,比如each
;如果你真的想使用地图你可以做这样的事情:
Object.keys(object).map(function(value, index) {
object[value] *= 3;
})
但是这很令人困惑,当看到map
时,人们会期望得到一个数组作为结果,然后用它做点什么。
答案 6 :(得分:2)
我认为你想要一个mapValues函数(将函数映射到一个对象的值上),这很容易实现自己:
mapValues = function(obj, f) {
var k, result, v;
result = {};
for (k in obj) {
v = obj[k];
result[k] = f(v);
}
return result;
};
答案 7 :(得分:2)
我知道它已经很长时间了,但仍然是最明显的折叠解决方案(也就是js中的减少),为了完整起见我将把它留在这里:
function mapO(f, o) {
return Object.keys(o).reduce((acc, key) => {
acc[key] = f(o[key])
return acc
}, {})
}
答案 8 :(得分:1)
下划线地图的混合修复 错误:P
_.mixin({
mapobj : function( obj, iteratee, context ) {
if (obj == null) return [];
iteratee = _.iteratee(iteratee, context);
var keys = obj.length !== +obj.length && _.keys(obj),
length = (keys || obj).length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys ? keys[index] : index;
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
if ( _.isObject( obj ) ) {
return _.object( results ) ;
}
return results;
}
});
一种简单的解决方法,可以保留正确的密钥并作为对象返回 它仍然使用与我可以使用此功能的客人相同的方式 覆盖bugy _.map函数
或者仅仅因为我将它用作mixin
_.mapobj ( options , function( val, key, list )
答案 9 :(得分:0)
您可以在Lodash中使用_.mapValues(users, function(o) { return o.age; });
,在下划线中使用_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
。
点击此处的交叉文档:http://jonathanpchen.com/underdash-api/#mapvalues-object-iteratee-identity
答案 10 :(得分:0)
const mapObject = (obj = {}, mapper) =>
Object.entries(obj).reduce(
(acc, [key, val]) => ({ ...acc, [key]: mapper(val) }),
{},
);
答案 11 :(得分:0)
_。map使用lodash之类的循环来实现这一目标
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}