[英]Map over object preserving keys
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}
帶下划線
_.mapObject
提供了一個函數_.mapObject
來映射值並保留鍵。
_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
與洛達什
Lodash 提供了一個函數_.mapValues
來映射值並保留鍵。
_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
// => { one: 3, two: 6, three: 9 }
我設法在 lodash 中找到了所需的函數,這是一個類似於下划線的實用程序庫。
http://lodash.com/docs#mapValues
_.mapValues(object, [callback=identity], [thisArg])
創建一個具有與對象相同的鍵和值的對象,這些值是通過回調運行對象的每個自己的可枚舉屬性而生成的。 回調綁定到 thisArg 並使用三個參數調用; (值、鍵、對象)。
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>
純 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})));
從ES2019 開始,您可以使用Object.fromEntries
。
let newObj = Object.fromEntries(Object.entries(obj).map(([k, v]) => ([k, v * 3])))
我知道這是舊的,但現在 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);
}
我知道這已經很長時間了,但是仍然缺少通過 fold(在 js 中也稱為 reduce)的最明顯的解決方案,為了完整起見,我將其留在這里:
function mapO(f, o) {
return Object.keys(o).reduce((acc, key) => {
acc[key] = f(o[key])
return acc
}, {})
}
_.map返回一個數組,而不是一個對象。
如果你想要一個對象,你最好使用不同的函數,比如each
; 如果你真的想使用地圖,你可以做這樣的事情:
Object.keys(object).map(function(value, index) {
object[value] *= 3;
})
但這令人困惑,當看到map
時,人們會期望有一個數組作為結果,然后用它做一些事情。
我認為您需要一個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) }),
{},
);
下划線映射錯誤的混合修復: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;
}
});
一個簡單的解決方法,保留正確的鍵並作為對象返回它仍然使用與我來賓相同的方式您可以使用此函數來覆蓋有問題的 _.map 函數
或者只是像我一樣將它用作 mixin
_.mapobj ( options , function( val, key, list )
您可以使用_.mapValues(users, function(o) { return o.age; });
在 Lodash 和_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });
在下划線。
在此處查看交叉文檔: http : //jonathanpchen.com/underdash-api/#mapvalues-object-iteratee-identity
_.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}
減少聰明看起來像上面的answare
_.reduce({one: 1, two: 2, three: 3}, function(result, num, key) {
result[key]=num * 3
return result;
}, {});
//output
{one: 1, two: 2, three: 3}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.