假设有如下测试数据(抓取了阮一峰老师的部分数据,希望阮老师不要介意):
[
{
"title": "周刊",
"href": "http://www.ruanyifeng.com/blog/weekly/",
"categories": [
{
"title": "科技爱好者周刊:第 80 期",
"href": "http://www.ruanyifeng.com/blog/2019/11/weekly-issue-80.html",
"publishTime": "2019-11-01",
"commentCounts": 18
},
{
"title": "科技爱好者周刊:第 79 期",
"href": "http://www.ruanyifeng.com/blog/2019/10/weekly-issue-79.html",
"publishTime": "2019-10-25",
"commentCounts": 44
}
]
},
{
"title": "创业",
"href": "http://www.ruanyifeng.com/blog/startup/",
"categories": [
{
"title": "谷歌的绩效管理",
"href": "http://www.ruanyifeng.com/blog/2016/03/performance-management.html",
"publishTime": "2016-03-29",
"commentCounts": 19
},
{
"title": "七个对我最重要的职业建议(译文)",
"href": "http://www.ruanyifeng.com/blog/2015/09/career-advice.html",
"publishTime": "2015-09-18",
"commentCounts": 47
}
]
}
]
然后我们需要处理如下问题:获取2019年评论最多的文章的名称
假设我们以命令式的编程思想来处理这个问题,那可能需要这样来解决:
1 // data 为上述数据
2 var maxCount = 0;
3 var maxTitle = '';
4 for (let i = 0; i < data.length; ++i) {
5 let categories = data[i].categories;
6 for (let j = 0; j < categories.length; ++j) {
7 let cat = categories[j];
8 if (cat.publishTime < '2019-01-01') {
9 continue;
10 }
11
12 if (maxCount < cat.commentCounts) {
13 maxCount = cat.commentCounts,
14 maxTitle = cat.title
15 }
16 }
17 }
18
19 console.log(`title: ${maxTitle}, comments: ${maxCount}`);
20 // => title: 科技爱好者周刊:第 79 期, comments: 44
然后我们以函数式的思想来解决这个问题:
1 var R = require('ramda');
2
3 // 文章列表保存在categories中, 所以首先我们要取这个属性
4 var getCates = R.map(R.prop('categories'));
5 // console.log(getCates(data)); // 这时输出的格式是一个二维数组: [[...], [...]]
6
7 // 我们需要将二维数组展开成一维数组
8 var unnestCates = R.compose(R.unnest, getCates);
9 // console.log(unnestCates(data)) // 这时我们就得到一个文章列表的一维数组了
10
11 // 接下去我们需要找出2019年发表的文章
12 var timeGt2019 = R.compose(R.lt('2019-01-01'), R.prop('publishTime'));
13 var getGt2019Cates = R.compose(R.filter(timeGt2019), unnestCates);
14 // console.log(getGt2019Cates(data));
15
16 // 然后我们对数组元素按照评论数进行降序排序
17 var descSort = R.sort(R.descend(R.prop('commentCounts')));
18 var getSorted2019Cates = R.compose(descSort, getGt2019Cates);
19 // console.log(getSorted2019Cates(data));
20
21 // 最后我们只需要取出数组的第一个元素即可
22 var result = R.head(getSorted2019Cates(data));
23
24 console.log(`title: ${result.title}, comments: ${result.commentCounts}`);
25 // => title: 科技爱好者周刊:第 79 期, comments: 44
可以看到我们获取到了正确的结果,接下去再对上面的代码进行简化:
1 var R = require('ramda');
2 var getMostCommentsCatIn2019 = R.compose(
3 R.head,
4 R.sort(R.descend(R.prop('commentCounts'))),
5 R.filter(
6 R.compose(
7 R.lt('2019-01-01'),
8 R.prop('publishTime'))
9 ),
10 R.compose(
11 R.unnest,
12 R.map(R.prop('categories'))
13 )
14 );
15
16 var result = getMostCommentsCatIn2019(data);
17 console.log(`title: ${result.title}, comments: ${result.commentCounts}`);
到此为止已经全部结束,大家可以看到使用函数式后,所有的循环和if判断都没有了,是不是很神奇呢~