【发布时间】:2021-07-03 02:33:56
【问题描述】:
我正在尝试将我的编程风格从 命令式 切换到 声明式,但是有一些概念让我感到困扰,比如 的性能循环。例如,我有一个原始 DATA,在操作后我希望得到 3 个预期结果:itemsHash、namesHash、rangeItemsHash
// original data
const DATA = [
{id: 1, name: 'Alan', date: '2021-01-01', age: 0},
{id: 2, name: 'Ben', date: '1980-02-02', age: 41},
{id: 3, name: 'Clara', date: '1959-03-03', age: 61},
]
...
// expected outcome
// itemsHash => {
// 1: {id: 1, name: 'Alan', date: '2021-01-01', age: 0},
// 2: {id: 2, name: 'Ben', date: '1980-02-02', age: 41},
// 3: {id: 3, name: 'Clara', date: '1959-03-03', age: 61},
// }
// namesHash => {1: 'Alan', 2: 'Ben', 3: 'Clara'}
// rangeItemsHash => {
// minor: [{id: 1, name: 'Alan', date: '2021-01-01', age: 0}],
// junior: [{id: 2, name: 'Ben', date: '1980-02-02', age: 41}],
// senior: [{id: 3, name: 'Clara', date: '1959-03-03', age: 61}],
// }
// imperative way
const itemsHash = {}
const namesHash = {}
const rangeItemsHash = {}
DATA.forEach(person => {
itemsHash[person.id] = person;
namesHash[person.id] = person.name;
if (person.age > 60){
if (typeof rangeItemsHash['senior'] === 'undefined'){
rangeItemsHash['senior'] = []
}
rangeItemsHash['senior'].push(person)
}
else if (person.age > 21){
if (typeof rangeItemsHash['junior'] === 'undefined'){
rangeItemsHash['junior'] = []
}
rangeItemsHash['junior'].push(person)
}
else {
if (typeof rangeItemsHash['minor'] === 'undefined'){
rangeItemsHash['minor'] = []
}
rangeItemsHash['minor'].push(person)
}
})
// declarative way
const itemsHash = R.indexBy(R.prop('id'))(DATA);
const namesHash = R.compose(R.map(R.prop('name')),R.indexBy(R.prop('id')))(DATA);
const gt21 = R.gt(R.__, 21);
const lt60 = R.lte(R.__, 60);
const isMinor = R.lt(R.__, 21);
const isJunior = R.both(gt21, lt60);
const isSenior = R.gt(R.__, 60);
const groups = {minor: isMinor, junior: isJunior, senior: isSenior };
const rangeItemsHash = R.map((method => R.filter(R.compose(method, R.prop('age')))(DATA)))(groups)
为了达到预期的结果,命令式只循环一次,而声明式循环至少3次(itemsHash,namesHash ,rangeItemsHash ) 。哪一个更好?性能上有什么取舍吗?
【问题讨论】:
-
"为了达到预期的效果,命令式只循环一次,而声明式循环多次。" 呃,因为你 使声明性代码循环多次。您可以在数据集上使用单个循环进行分组。在 Ramda 中,那是
groupBy/groupWith -
1,您可以向我展示获得这 3 个结果的优化代码吗? 2、
groupBy可能适合这个例子,但是当涉及到更复杂的场景时,那该怎么办呢? -
我的意思是实现
rangeItemsHash,groupBy的 1 个单循环就可以了。但是另外两个itemsHash、namesHash呢?他们不采取两行循环吗?
标签: javascript functional-programming ramda.js declarative-programming