函数式编程-函数组合

函数组合

  • 概念解析
  1. 函数组合是一个数学概念,允许您将两个或更多个函数组合到一个新函数中。
  2. 功能组合的关键是具有可组合的函数,即组合的函数应该有1个输入参数和1个输出值(如果有多个参数,通过函数curry去实现)
  3. 示例
const compose = (...functions) => data =>
  functions.reduceRight((value, func) => func(value), data)

const encodeAttribute = (x = '') =>
      x.replace(/"/g, '"')

    const toAttributeString = (x = {}) =>
      Object.keys(x)
      .map(attr => `${encodeAttribute(attr)}="${encodeAttribute(x[attr])}"`)
      .join(' ')

    const tagAttributes = x => (c = '') =>
      `<${x.tag}${x.attr?' ':''}${toAttributeString(x.attr)}>${c}</${x.tag}>`

    const tag = x =>
      typeof x === 'string' ?
      tagAttributes({
        tag: x
      }) :
      tagAttributes(x)

    const listGroup = tag({
      tag: 'ul',
      attr: {
        class: 'list-group'
      }
    })
    const listGroupItem = tag({
      tag: 'li',
      attr: {
        class: 'list-group-item'
      }
    })
    const listGroupItems = items =>
      items.map(listGroupItem)
      .join('')

    listGroup()
    
    listGroupItem('Cras justo')
    
    listGroupItems(['Cras justo', 'Dapibus ac'])
   
    listGroup(listGroupItems(['Cras justo', 'Dapibus ac']))
    
    compose(listGroup, listGroupItems)(['Cras justo1', 'Dapibus ac2', 'Cras justo3', 'Dapibus ac4'])
   
复制代码
  • 解析reduceRight函数
// 函数接收一个callback,有四个参数,
// 每次回调的各参数值请参考表格
// initialValue:作为第一次调用 //callbackfn函数的第一个参数
var arr = [0,1,2,3,4]; 
arr.reduceRight(function (preValue,curValue,index,array) { return preValue + curValue; }, initialValue); 
复制代码
preValuecurValueindexarray返回值
011[0,1,2,3,4]1
122[0,1,2,3,4]3
333[0,1,2,3,4]6
644[0,1,2,3,4]10
  • 完整代码(html的生成,比拼字符串有意思多了)
console.clear()

/***********************************************************
 * functional.js
 ***********************************************************/
const compose = (...functions) => data =>
  functions.reduceRight((value, func) => func(value), data)

const set = prop => obj => value =>
  (obj[prop] = value, obj)

const map = f => x =>
  Array.prototype.map.call(x, f)

const join = seperator => list =>
  Array.prototype.join.call(list, seperator)

/***********************************************************
 * dom.js
 ***********************************************************/
const setInnerHtml = set('innerHTML')

/***********************************************************
 * html.js
 ***********************************************************/
const encodeAttribute = (x = '') =>
  x.replace(/"/g, '&quot;')

const toAttributeString = (x = {}) =>
  compose(
    join(' '),
    map(attr => `${encodeAttribute(attr)}="${encodeAttribute(x[attr])}"`),
    Object.keys
  )(x)

const tagAttributes = x => (contents = '') =>
  `<${x.tag}${x.attr?' ':''}${toAttributeString(x.attr)}>${contents}</${x.tag}>`

const tag = x =>
  typeof x === 'string'
    ? tagAttributes({ tag: x })
    : tagAttributes(x)

// list-group
const listGroupTag = tag({ tag: 'ul', attr: { class: 'list-group' }})
const listGroupItem = tag({ tag: 'li', attr: { class: 'list-group-item' }})
const listGroupItems = list =>
  list.map(listGroupItem)
    .join('')
const listGroup = compose(listGroupTag, listGroupItems)

// panel
const panelTag = tag({ tag: 'div', attr: { class: 'panel panel-default' }})
const panelBody = tag({ tag: 'div', attr: { class: 'panel-body' }})
const basicPanel = compose(panelTag, panelBody)

const listGroupPanel = compose(basicPanel, listGroup)

/***********************************************************
 * main.js
 ***********************************************************/
const content = document.getElementById('content')
const main = e =>
  compose(setInnerHtml(e), listGroupPanel)

const list = [
  'Cras justo odio',
  'Dapibus ac facilisis in',
  'Morbi leo risus',
  'Porta ac consectetur ac',
  'Vestibulum at eros'
]

main(content)(list)

复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值