2012-06-11 30 views
9

是否沒有無處不在/標準的Javascript或Coffeescript函數轉換對象/地圖/散列值?任何轉換對象*值*的Javascript或Coffeescript`map`函數?

jQuery has $.map但它只生成Array
Underscore has _.map但它也只產生Array

要清楚,像這樣的功能就是我正在尋找的功能。 (這個例子是寫在CoffeeScript中不使用Javascript)

# Transforms the values in a map. (Doesn't modify `obj` — returns a new map.) 
# Example usage: 
# mapObjVals({ a: 'aa', b: 'bb'}, (key, value) -> value + '_!') 
# --> { a: 'aa_!', b: 'bb_!' } 
mapObjVals = (obj, f) -> 
    obj2 = {} 
    for k, v of obj 
    obj2[k] = f k, v 
    obj2 
+1

你似乎已經回答了你自己的問題:)只要確保你使用'爲自己的k,v的obj'來防止被原型擴展位。我會直接使用'for'循環而不是輔助函數,因爲這是一種罕見的現象。 –

回答

6

如果你想一個對象映射到一個對象,你需要使用一個fold(傳統的功能術語)或reduce(常見的現代名稱,用下劃線使用),它建立從集合的新值:

_.reduce(obj, function(newObj, thisValue, thisKey) { 
     // modify newObj based on thisKey/thisValue 
     return newObj; 
     }, {}) 

作爲第二個參數傳遞的功能是爲每個鍵/值對調用一次。它作爲第一個參數傳入正在構建的對象中,後面是當前值,後面是關聯的鍵。這取決於修改對象並返回其新值的功能。

_.reduce的第三個參數是要使用第一個鍵/值對傳入的新對象的初始值;在這種情況下,它是一個空對象/地圖/散列表{}

縮小/摺疊/插入通常用於求和值。基本上,任何時候你想從一個集合構造一個新的單值。 map實際上只是reduce的特殊情況,據稱減價值實際上是與原始大小相同的另一個集合。

對於CoffeeScript,AFAIK,列表推導總是返回列表,即使在迭代對象時也是如此。所以你可能想看看the CoffeeScript version of Underscore

+0

謝謝!我得到了我的'+'_!''例子,使用'_.reduce'如下:'_({a:'aa',b:'bb'})。reduce((memo,value,index) - >備忘錄[index] = value +'_!';備忘錄),{}' – KajMagnus

+1

「可惜」,用'_.reduce',我必須從迭代器中返回'memo',並且2)通過' }'減少'。所以它有些更冗長。實際上,我發現我的示例函數更容易理解 - 當我讀取mapObjVals({a:'aa',b:'bb'},(key,value) - > value +'_!')'我很快理解正在做什麼。 – KajMagnus

+0

是的,減少更詳細,因爲它更一般;地圖可以很容易地在減少方面實施。無論你是否覺得需要編寫一個輔助函數來隱藏這種冗長都取決於個人喜好。 –

相關問題