我已经开始学习Ramda.js和函数式编程,并且对使用无点编程风格的函数式组合非常感兴趣,但是我很难理解其中的一些内容,我希望有人可以帮助说明:
假设我有一份人员名单 - 我只想获取 13-19 岁(青少年)之间的人。然后,我想将每个人映射到该人的getName()
方法的返回值(如果它存在),或者他们的name
属性。然后,我想.toUpperCase()
点名。
如果我使用常规的 JS 原型方法,我不会使用Array.prototype.filter
来获取青少年用户,然后Array.prototype.map
. 出于性能原因,我会使用Array.prototype.reduce
,其主体将由一个条件保护,该条件检查每个迭代项目是否符合青少年的标准。这样,我就少了一次迭代。Elijah Manor 在他的博客上有一篇关于此的文章。
这是我使用R.filter
and提出的无点 Ramda 代码R.map
(按预期工作):
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