2016-02-29 95 views
0

最近我發現自己在我的應用程序中越來越多地使用關聯數組(或hastables)(優點是查找速度快,重複刪除等)。使用Ramba,下劃線或純Javascript創建關聯數組的最佳方法?

這裏是我的應用程序所採取的典型代碼 -

var parent1 = { id: 5, name: 'parent 1'}, parent2 = { id: 10, name: 'parent 2'}; 
var children = [{id: 1, parent: parent1}, {id: 2, parent: parent1}, {id: 3, parent: parent1}, {id: 4, parent: parent2}] 

var addToHash = function (hashObj, child) { 
    var parent = child.parent; 
    hashObj[parent.id] = parent; 
    return hashObj; 
}; 

var uniqueParents = R.reduce(addToHash, {}, children); 

目前我使用Ramda減少功能。

問題 - 有沒有更好的(更簡潔)的方式來做到這一點與Ramda,另一個第三方庫或簡單地在簡單的香草JavaScript?

+0

什麼是輸入/輸出? – Amit

+1

您是否需要單獨定義功能?例如,你在重複使用它?你可以分解共同點幷包裝'減少'? (雖然坦率地說,'reduce'在這裏沒有爲你做任何事情。) –

+0

這看起來像一個簡單的'for'會做的(如果你想感覺「更多功能」,你可以做'forEach') – Amit

回答

1

一種可能性:

R.pipe(
    R.map(prop('parent')),    //=> [parent1, parent1, parent1, parent2] 
    R.uniq,        //=> [parent1, parent2] 
    R.map(parent => [parent.id, parent]), //=> [[5, parent1], [10, parent1]] 
    R.fromPairs       //=> {5: parent1, 10: parent2} 
)(children); 
//=> {5: {id: 5, name: 'parent 1', 10: {id: 10, name: 'parent 2'}}} 

請注意,如果你只是想uniq的父母的列表,而不是HashMap的,你可以在管道中的第二個功能後停止。

另一種選擇,類似於你的,它只是將你的功能於一體,它返回一個新的累加器,而不是變異,它是:

var parentMap = R.reduce((acc, child) => R.assoc(child.parent.id, child.parent, acc), {}); 
parentMap(children); //=> {5: {id: 5, name: 'parent 1', 10: {id: 10, name: 'parent 2'}}} 
1

reduce(Ramda's或JavaScript自己的)在這裏沒有買任何東西,它只是增加了一個編寫bug的機會(忘記返回hashObj),我主觀地認爲語義關閉。 reduce適用於當累加器更改時,如總結數組中值的經典示例。

您可以通過給自己一個可重複使用的功能,在手對工作更適合更簡潔:

function buildHash(hash, array, callback, thisArg) { 
    array.forEach(function(entry) { 
     callback.call(thisArg, hash, entry); 
    }); 
    return hash; 
} 

然後:

var addToHash = function(hash, child) { 
    var parent = child.parent; 
    hash[parent.id] = parent; 
}; 
var uniqueParents = buildHash({}, children, addToHash); 

或者作爲Array.prototype擴展你Object.defineProperty添加如此毫無防備的for-in環路不會被絆倒:

Object.defineProperty(Array.prototype, "buildHash", { 
    value: function buildHash(hash, array, callback, thisArg) { 
     array.forEach(function(entry) { 
      callback.call(thisArg, hash, entry); 
     }); 
     return hash; 
    } 
}); 

然後它是相同的addToHash,但通話更加簡潔:

var uniqueParents = children.buildHash({}, addToHash); 

而所有這些獲得更多的短暫,如果你正在使用ES2015的箭頭功能。 :-)

+0

謝謝,很好的答案。我想我會將Object.defineProperty片段集成到我的應用程序中。 –

+0

@JoeKing:只要你不需要支持IE8(或者IE9-11處於[in]兼容模式)。 :-) –

+0

感謝您的提示,即使我們只支持IE10 +,我從來沒有考慮過一些客戶可能在兼容模式下運行:( –

相關問題