2014-09-24 95 views
17

Underscore.js在集合上提供了_.each_.map,這很好,但我需要迭代我的對象的所有屬性。我需要修改這些值並保留這些鍵。例如。我有這樣的:{a:1, b:2, c:3},我需要執行一個操作,更改值,但保留鍵。比方說,我會計算廣場,我應該得到{a:1, b:4, c:9}。問題是:如何使用下劃線(對香草javascript不感興趣)?我喜歡像一個方法:迭代對象屬性並修改它們

var a = {a:1, b:2, c:3} 
_.magic(a, function(item){ return item*item; }); 

此外,這將是巨大的,如果這是可能的連鎖它,因爲我做的地圖,轉儲結果執行每個然後再使用地圖(因爲我需要)。

回答

14

我看起來更進我的一些片段一點點,看看是否有變異原始對象的選擇,但我沒有發現什麼有趣的,所以我跟this去:\

var original = {a:1, b:2, c:3}; 
var squaredValues = _.object(_.map(original, function (value, key) { 
    return [key, value * value]; 
})); 

我希望有一個更優雅的解決方案。

1

非常感謝Javier92誰指出我正確的解決方案。

反正,我不喜歡使用使用另外兩個下劃線的方法下劃線方法(它不是可讀的那麼多),所以我想出了被混合到下劃線一個簡單的包裝功能:

// mixin to make our new function available via _ 
_.mixin({ 
    updateAttributes: function(object, iteratee) { 
     return _.object(_.map(object, function (value, key) { 
      return [key, iteratee(value)]; 
     })); 
    } 
}); 

在你的代碼的地方使用它:

_.updateAttributes({a:1, b:2, c:3}, function(item){ return item*item; }) 
// Object {a: 1, b: 4, c: 9} 

想不出一個字的功能(可能還有比updateAttributes更好的東西)。

+6

螺破折號具有此爲[_.mapValues](HTTP ://lodash.com/docs#mapValues) – 2014-09-24 14:56:48

33

_.mapObjectadded in version 1.8)正是你要找的。


對於先前的版本,可以使用第三個參數_.each回調變異原始對象。

_.each({a:1, b:2, c:3}, function(value, key, obj) { obj[key] = value * value; }); 

使用帶初始備忘錄的_.reduce也可以創建一個全新的對象。

_.reduce({a:1, b:2, c:3}, function(memo, value, key) { 
    memo[key] = value * value; 
    return memo; 
}, {}); 

我更喜歡_.reduce的方法。一個簡單的mixin將使其行爲完全像_.map

_.mixin({ 
    magic: function(obj, iterator, context) { 
     return _.reduce(obj, function(memo, value, key) { 
      memo[key] = iterator.call(context, value, key, obj); 
      return memo; 
     }, {}); 
    } 
}); 
3

賈斯汀說_.mapObject可能是你所期待的。 但是這會創建一個新的對象(擴展爲{}),它可能不是您想要的(例如,如果它不是像new THREE.Vector3()這樣的簡單對象),那麼用不同的東西替換原始對象並不好。

對於這種情況(在修改代替值給定的對象),只要用_.each與iteratee函數的第三個參數:

_.each(complexObject, function(value, key, obj) { 
    obj[key] = value * value; 
});