• 函数式编程实战(一)


    假设有如下测试数据(抓取了阮一峰老师的部分数据,希望阮老师不要介意):

    [
      {
        "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判断都没有了,是不是很神奇呢~

  • 相关阅读:
    Swift与OC混合开发
    Swift继承
    Swift方法
    Swift属性
    Swift闭包
    Swift结构体和类
    Swift函数
    Swift基础语法
    Xcode使用篇-重新安装Xcode
    iOS组件化开发-CocoaPods安装
  • 原文地址:https://www.cnblogs.com/Farmer-D/p/11778524.html
Copyright © 2020-2023  润新知