Js 中的 map函数,如果使用 javascript 对象调用,则返回从对象值映射的值数组。
map
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; }); => [3, 6, 9]
有没有一种方法可以使它保存键? 即,我想要一个函数返回
{one: 3, two: 6, three: 9}
_. map 返回 Array,而不是 Object。
如果你想要一个对象,你最好使用不同的函数,比如 each; 如果你真的想要使用 map,你可以这样做:
each
Object.keys(object).map(function(value, index) { object[value] *= 3; })
但是,这是令人困惑的,当看到 map时,人们会希望有一个数组作为结果,然后使用它做一些事情。
用 下划线
下划线提供了一个函数 _.mapObject来映射值并保留键。
_.mapObject
_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; }); // => { one: 3, two: 6, three: 9 }
DEMO
用 Lodash
Lodash 提供了一个函数 _.mapValues来映射值并保留键。
_.mapValues
_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; }); // => { one: 3, two: 6, three: 9 }
我认为你需要一个 地图价值函数(将一个函数映射到一个对象的值上) ,这个函数很容易自己实现:
mapValues = function(obj, f) { var k, result, v; result = {}; for (k in obj) { v = obj[k]; result[k] = f(v); } return result; };
我设法在 loash 中找到了所需的函数,这是一个类似于下划线的实用程序库。
Http://lodash.com/docs#mapvalues
_.mapValues(object, [callback=identity], [thisArg]) 创建一个对象,该对象的键与 通过回调运行对象的每个自己的可枚举属性。 回调函数绑定到 this Arg,并用三个参数调用; (value,key,object).
_.mapValues(object, [callback=identity], [thisArg])
创建一个对象,该对象的键与 通过回调运行对象的每个自己的可枚举属性。 回调函数绑定到 this Arg,并用三个参数调用; (value,key,object).
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>
下划线映射 臭虫: 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 函数
或者只是我把它用作混音器
_.mapobj ( options , function( val, key, list )
我知道这很老套,但是现在 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); }
这个版本的纯 JS (ES6/ES2015)怎么样?
let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));
Jsbin
如果你想映射一个对象 递归(映射嵌套 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:
Object.entries
Object.keys
let newObj = Object.assign(...Object.entries(obj).map(([k, v]) => ({[k]: v * 3})));
因为 ES2019你可以使用 Object.fromEntries。
Object.fromEntries
let newObj = Object.fromEntries(Object.entries(obj).map(([k, v]) => ([k, v * 3])))
你可以在 Lodash 使用 _.mapValues(users, function(o) { return o.age; });,在下划线中使用 _.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });。
_.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
我知道这已经很长时间了,但是仍然缺少最明显的通过摺叠(也就是在 js 中减少)的解决方案,为了完整起见,我将它留在这里:
function mapO(f, o) { return Object.keys(o).reduce((acc, key) => { acc[key] = f(o[key]) return acc }, {}) }
const mapObject = (obj = {}, mapper) => Object.entries(obj).reduce( (acc, [key, val]) => ({ ...acc, [key]: mapper(val) }), {}, );
_. map 使用 loash 样的循环来实现这一点
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({one: 1, two: 2, three: 3}, function(result, num, key) { result[key]=num * 3 return result; }, {}); //output {one: 1, two: 2, three: 3}