Function Programming - 柯里化(curry)

看到一篇很是不錯的文章,這裏分享給你們:http://www.jianshu.com/p/fa3568087881javascript

首先,柯里化的定義:你能夠只透過部分的參數呼叫一個function,它會回傳一個function 去處理剩下的參數。java

咱們從最簡單的栗子開始:函數

var add  = function(a) {
  return function(b) {
    return a + b;
  }
}

var addTen = add(10);

addTen(5);    // 15

同時,咱們還能夠這樣調用:

add(10)(5);   //15

  上述add函數是柯里化以後的函數,通常咱們會以下定義add函數:工具

var add = function(a, b) {
  return a + b;
}

  通常的定義有什麼問題呢,參數可能不當心多了,那多餘的參數就會被忽略,也有可能傳參傳少了,那麼函數執行會發生錯誤;而柯里化若是傳部分參數只會返回要處理剩下參數的函數,make sense?blog

固然咱們有工具使咱們的函數柯里化,這裏咱們舉例用lodash的https://lodash.com/docs/4.17.4#curryip

var add = _.curry(function(a, b) {
  return a + b;
})

var addTen = add(10);

addTen(5);    // 15

同時,柯里化也接受傳多個參數:

add(10)(5);   //15

  咱們再稍微深刻理解一下:get

var object = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getIds = object.map(o => (o.id));

  上述代碼明顯是取objec裏面各個id;這有個什麼問題呢?咱們沒有辦法重用getIds這個函數,由於每次想拿到id,都得進行一次map和取id的操做,咱們再改進下這個函數:it

var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getId = (object) => (object.id);
var getIds = objects.map(getId);    //解釋下爲啥這裏能夠不用參數直接能夠調用getId,由於fp(Function Programming)中函數是一等公民,function(a) {return getId(a);} 與 getId是等價的;

  這樣的,咱們抽出去裏getId這個函數,可是依然不能徹底重用,由於每次還要進行一次map操做,再一次改進:io

var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];
var getId = (object) => (object.id);
var getIds = _.curry((objects) => objects.map(getId));

getIds(objects);   //[1,2,3]

  這個時候咱們就用到裏柯里化,可是依然不夠好,由於若是我想拿到每一個object的name呢,這個方法就作不到,咱們就再一次改進看看:function

var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];

var getValues = _.curry((objects, key) => objects.map((object) => (object[key])));

getValues(objects, 'name')

 這樣的話,咱們就能取任何key的值了,只須要傳入objects和key便可。

var objects = [{id: 1, name: 'test'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}];

var getId = _.curry((property, object) => (object[property]));
var map = _.curry((fn, objects) => objects.map(fn));
var getValues = map(getId('id')); getValues(objects); 因爲咱們對key值進行的操做可能不同,因此咱們能夠傳一個函數;

  這就是咱們所介紹的curry啦,歡迎各位留言,提反饋!

相關文章
相關標籤/搜索