我从命令式编程背景(JAVA),并开始尝试理解FP概念更好地很。特别是条件分支/过滤以及它如何应用于流/数据列表。函数式编程:列表条件分支/过滤(JavaScript)的
这里是一个傻人为的例子......我们的球员名单,并想将它们分为基于他们的技能水平不同的名单。一个基本的必要方法可以是这样的:
const excluded = []; // LOW skilled
const reserves = []; // only MEDIUM/HIGH skilled
const team = []; // only HIGH skilled
const allPlayers = [
{
name: 'personh1',
skillLevel: 'HIGH'
},
{
name: 'personh2',
skillLevel: 'HIGH'
},
{
name: 'personh3',
skillLevel: 'HIGH'
},
{
name: 'personm1',
skillLevel: 'MEDIUM'
},
{
name: 'personm2',
skillLevel: 'MEDIUM'
},
{
name: 'personl1',
skillLevel: 'LOW'
},
{
name: 'personl2',
skillLevel: 'LOW'
}
];
const maxTeamSize = 2;
const maxReservesSize = 2;
allPlayers.forEach(p => {
if (p.skillLevel === 'HIGH') {
if (team.length < maxTeamSize) {
team.push(p);
} else {
reserves.push(p);
}
} else if (p.skillLevel === 'MEDIUM') {
if (reserves.length < maxReservesSize) {
reserves.push(p);
} else {
excluded.push(p);
}
} else {
excluded.push(p);
}
});
// functions defined elsewhere...
notifyOfInclusion(team.concat(reserves));
notifyOfExclusion(excluded);
我可以在一个功能更强大的方式做到这一点:(使用JS和Ramda库):
team = R.slice(0, maxTeamSize, R.filter(p => p.skillLevel === 'HIGH', allPlayers));
reserves = R.slice(0, maxReservesSize, R.filter(p => (p.skillLevel === 'HIGH' || p.skillLevel === 'MEDIUM') && !R.contains(p, team), allPlayers));
excluded = R.filter(p => !R.contains(p, team) && !R.contains(p, reserves), allPlayers);
notifyOfInclusion(team.concat(reserves));
notifyOfExclusion(excluded);
但看起来很简陋,重复的,不是很说明性的。什么是从功能性POV中实现类似的更好(更优雅/陈述式)的方式?在任何答案中使用拉姆达将是一个奖金,但不是必需的。谢谢。
如果您不介意队伍中的“MEDIUM”球员和储备中的“LOW”球员在没有足够的球员的情况下,您可以使用'R.sortBy'技能水平,然后选择'R.slice'。 – GingerPlusPlus