【发布时间】:2016-05-01 17:49:09
【问题描述】:
我已经开始学习 Ramda.js 和函数式编程,并且对使用无点编程风格的函数式组合非常感兴趣,但是我很难理解其中的一些内容,我希望有人可以帮助说明:
假设我有一个人员列表 - 我只想获取 13-19 岁(青少年)之间的人。然后,我想将每个人映射到该人的 getName() 方法(如果存在)的返回值,否则映射到他们的 name 属性。然后,我想打电话给.toUpperCase()。
如果我使用常规的 JS 原型方法,我不会使用 Array.prototype.filter 来获取青少年用户,然后使用 Array.prototype.map。出于性能原因,我将使用Array.prototype.reduce,其主体将由一个条件保护,该条件检查每个迭代项目是否符合青少年的标准。这样,我就少了一次迭代。 Elijah Manor has an article about this on his blog.
这是我使用 R.filter 和 R.map 提出的无点 Ramda 代码(按预期工作):
var people = [
{ name: 'Bob', gender: 'male', age: 22 },
{ name: 'Jones', gender: 'male', age: 15 },
{ name: 'Alice', gender: 'female', age: 19 },
{ name: 'Carol', gender: 'female', age: 32 },
{ name: 'Odu', gender: 'male', age: 25 },
{ name: 'Fred', gender: 'male', age: 55 },
{ name: 'Nicole', gender: 'female', age: 29 },
{ getName: function() { return 'David' }, gender: 'male', age: 23 }
]
var getUpcasedTeenagerNames = R.pipe(
R.filter(
R.propSatisfies(R.both(R.lte(13), R.gte(19)), 'age')
),
R.map(
R.pipe(
R.ifElse(
R.propIs(Function, 'getName'),
R.invoker(0, 'getName'),
R.prop('name')
),
R.toUpper
)
)
)
getUpcasedTeenagerNames(people) // => ['JONES', 'ALICE']
我的问题是 - 我将如何重写上述算法的以下本机版本以使用无点 Ramda.js?
var getUpcasedTeenagerNames = function(people) {
return people
.reduce(function(teenagers, person) {
var age = person.age
if (age >= 13 && age <= 19) {
var name
if (typeof (name = person.getName) === 'function') {
name = name()
} else {
name = person.name
}
teenagers.push(name.toUpperCase())
}
return teenagers
}, [])
}
我尝试过使用R.scan,查看过使用R.reduced 和R.when,但我担心我可能会漏掉一点。
为方便起见,我在 Ramda REPL 中包含以下代码:http://goo.gl/6hBi5k
【问题讨论】:
-
请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
标签: javascript functional-programming reduce pointfree ramda.js