前端算法(柯里化)

293 阅读2分钟

前言

柯里化就是把接收多个参数的函数转化成接收单一参数的函数,并且返回一个(可以接收剩余参数的)新函数。
优点:可以延迟计算,也就是调用柯里化函数时传入的参数不是立即调用的,而是只有当满足一定条件时
才会(将已经在数组中存储的参数作为参数)执行;参数可以复用,当多次调用同一个函数,并且传递的
参数绝大多数是相同的,那么该函数可能是一个很好的柯里化函数。

实现

1.lodash中的curry方法就是一个柯里化函数 www.lodashjs.com/docs/lodash…

2.自己实现一个通用的柯里化函数


function sum(a,b,c,d) {
    return a + b + c + d;
}
const curring = (fn:Function) => {
        const exec = (sumArgs:any[] = []) => {
        return sumArgs.length >= fn.length ? fn(...sumArgs) 
      : (...args) => exec([...sumArgs,...args])
    }
    return exec()   //exec()的参数可以是初始化的值,可以是重复传递的参数
}
let test = curring(sum)(......)
//"......"指的是传递给sum函数的参数,形式有两种,如1.(1,2,3,4) 2. (1,2)(3)(4)......

场景

减少重复不变的参数

实现url的拼接,如果我们要拼接一个url,即协议+域名+路径,那么重复参数的情况便出现,如协议是http还是https?如下

function splicingUrl(protocol,domain,path){
        return `${protocol}://${domain}/${path}`
}
splicingUrl(http,www.baidu.com,home)
splicingUrl(https,taobao.com,datail)

下面通过柯里化实现减少传递重复参数的功能

function splicingUrl(protocol,domain,path){
        return `${protocol}://${domain}/${path}`
}
const curryPackage = (fn:Function) => {
        const curryFunc = (splicingArgs:any[] = []) => {
            return splicingArgs.length >= fn.length ? fn(...splicingArgs) 
        : (...args) => curryFunc([...splicingArgs,...args])
    }
    return curryFunc()
}
let newCurry = curryPackage(splicingUrl)('http','www.baiducom')
newCurry('home.html')   //http://www.baiducom/home.html
newCurry('photo.html')  //http://www.baiducom/photo.html

将柯里化之后的callback参数传递给map/filter等函数

let studentsInfo = [{name:'tom',age:19},{name:'jarry',age:32},{name:'susan',age:33}]
function getObj(key,obj){
    return obj[key]
}
//将callback进行柯里化
import _ from 'lodash';
let curryCallback = _curry(getObj)
let nameArray = studentsInfo.map(curryCallback('name'));  // ['tom','jarry','susan']
let agesArray = studentsInfo.map(curryCallback('age'));   // [19,32,33]