Ramda学习

Rmada文档http://ramdajs.com/docs

Ramada是函数是编程的典范

有两种重要的特点

  • Ramda函数参数的特点是 函数第一,数据第二(function first,data last)。也就是说 函数排在前面,data排在后面
  • Ramda函数都是柯里化curried的,也就是说所有多参数的函数都可以单参数调用。

引入ramda

var R = require('ramda');

比较运算

  1. 大于 gt 大于等于 gte 小于 lt 小于等于 lte 比较两个值是否相等 equals 支持对象比较

大于

> R.gt(2)(1);
true
> R.gt('a')('z');
false
>

大于等于

> R.gte(2)(2)
true
> R.gte('a')('z')
false
>

小于

> R.lt(2)(1)
false
> R.lt('a')('z')
true

小于等于

> R.lte(2)(2)
true
> R.lte('a')('z')
true
>

相等

> R.equals(1)(1)
true
> R.equals(1)('1')
false
> R.equals([1,2,3])([1,2,3])
true

eqBy:比较两个值传入指定函数的运算结果是否相等。

> R.eqBy(Math.abs,5)(-5)
true

数学运算

加 add 减 subtract 乘 multiply 除 divide

> R.add(7)(3)
10
> R.subtract(7)(3)
4
> R.multiply(7)(3)
21
> R.divide(7)(3)
2.3333333333333335

逻辑运算

与 both 或 either 接受两个函数作为参数。

allPass 接受一个函数数组作为参数,所有的函数都返回true 时 才为真,否则就是假

> var gt10 = x=>x>10;
> var even = x=>x%2===0;
// both
> var f = R.both(gt10,even);
> f(15)
false
> f(16)
true
// either
> var f = R.either(gt10,even);
> f(16)
true
> f(15)
true
// allPass
> var f = R.allPass([gt10,even]);
> f(15)
false
> f(16)
true

字符串

split: 按指定字符把字符串拆分成数组

> R.split('.')('a.bc.x.yx');
[ 'a', 'bc', 'x', 'yx' ]

test:判断一个字符串是否和正则表达式匹配

> R.test(/^x/)('xyz')
true
> R.test(/^x/)('yz')
false

match: 返回一个字符串的匹配结果

> R.match(/([a-z]a)/g)('bananas');
[ 'ba', 'na', 'na' ]

函数

函数的合成

pipe : 将多个函数合并成一个函数,从左向右执行

// 先取绝对值 再加1 再乘2
> R.pipe(Math.abs,R.add(1),R.multiply(2))(-4)
10

compose: 将多个函数合并成一个函数,从右到左执行

// 从右向左 先乘以2 再加1 再取绝对值
> R.compose(Math.abs,R.add(1),R.multiply(2))(-4)
7

converge: 本意是汇聚的意思。 需要两个参数,第一个参数是一个函数,第二个参数是个函数数组
,传入的值先使用数组中的函数依次处理之后,把返回的结果交给第一个参数处理。

var sumOfArr = arr => {
    var sum = 0;
    arr.forEach(i => sum += i);
    return sum;
  };

  var lengthOfArr = arr => arr.length;

  var average = R.converge(R.divide,[sumOfArr,lengthOfArr])([1,2,3,4,5,6,7]);
  console.log(average);// 4 相当于28 除以4

柯里化

curry: 将多参数的函数,转换成单参数的形式

 var add = (x,y)=>x+y;
  var curriedAdd = R.curry(add);
  console.log(curriedAdd(3)(5));//8

partial: 允许多参数的函数接受一个数组,指定最左边的部分参数

 var partialAdd = R.partial(add,[3]);
  console.log(partialAdd(5));


  var tell = (from,to,words)=>from +'对' + to + '说:' + words;

  var partialTell = R.partial(tell,['小明','小红']);
  console.log(partialTell('晚上来我家玩'));//小明对小红说:晚上来我家玩

partialRight 和partial 但数组指定的是最右边的参数

  var partialRightTell = R.partialRight(tell,['晚上来我家玩']);
  console.log(partialRightTell('小亮','小丽'));//小亮对小丽说:晚上来我家玩

 console.log(partialRightTell('小亮','小丽','我们一起过家家'));//小亮对小丽说:我们一起过家

useWith:接受一个函数fn和一个函数数组作为参数,返回fn的柯里化版本,该新函数的参数,先分别经过对应的函数数组处理,再传入fn执行

  var decreaseOne = x => x - 1;
  var increaseOne = x => x + 1;
  
 var res = R.useWith(Math.pow, [decreaseOne, increaseOne])(3, 4) // 32
 // 3 经过 decreaseOne处理 4 经过increaseOne 处理 返回给 Math.pow 处理
console.log(res);

R.useWith(Math.pow, [decreaseOne, increaseOne])(3)(4);//32 

memoize: 返回一个函数,会缓存每一次的运行结果

当使用同一个参数函数多次调用时,只会执行一次,后续执行,直接返回上一次的执行结果

var count = 1;
var increaseNum = (num)=>{
    count += 1;
    console.log('hello');
};

var f = R.memoize(increaseNum);

f(3);
console.log(count);
f(3);
console.log(count);
f(3);
console.log(count);

//打印结果
hello
2
2
2

complement : 互补,如果原函数返回true 该函数就返回false 如果是false就返回true

var gt10 = x => x > 10;
var lte10 = R.complement(gt10);
gt10(7) // false
lte10(7) // true

函数的执行

binary 参数函数执行时,只传入最前面两个参数

var takesThreeArgs = function(a, b, c) {
  return [a, b, c];
};

var takesTwoArgs = R.binary(takesThreeArgs);
takesTwoArgs(1, 2, 3) // [1, 2, undefined]

tap:将一个值传入指定函数,并返回该值。

var sayX = x=>console.log('x is ' + x);
var res = R.tap(sayX)(10);
console.log(res);

// 打印结果
x is 10
10

zipWith:将两个数组对应位置的值,一起作为参数传入某个函数。

var withf = (x,y)=>{
    console.log(x,y);
    return [x,y]
}

var res = R.zipWith(withf,[1,2,3])([4,5,6]);
console.log(res);

//输出结果
1 4
2 5
3 6
[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]

apply:将数组转成参数序列,传入指定函数。

比如Math.max接受序列作为参数而不是数组

var lists = [1,2,3,4,5,100,20,-200];
console.log(R.apply(Math.max)(lists));

applySpec:返回一个模板函数,该函数会将参数传入模板内的函数执行,然后将执行结果填充到模板。

var getMetrics = R.applySpec({
    sum:R.add,
    nested:{
        mul:R.multiply
    }
});

var res = getMetrics(2)(4);
console.log(res);

ascend:返回一个升序排列的比较函数,主要用于排序。deascend 相反,返回一个降序的比较函数

var byAge = R.ascend(R.prop('age'));
var people = [
    {
        age:100,
        name:'old'
    },{
        age:50,
        name:'mid'
    },
    {
        age:18,
        name:'young'
    }
];
var peopleByYoungestFirst = R.sort(byAge, people);

console.log(peopleByYoungestFirst);

//结果
[ { age: 18, name: 'young' },
  { age: 50, name: 'mid' },
  { age: 100, name: 'old' } ]

数组

特征判断

contains:如果包含某个成员,返回true。

var contains1 = R.contains(3)([1,2,3,5]);
var contains2 = R.contains(4)([1,2,3,5]);
console.log(contains1,contains2);//true false

all:所有成员都满足指定函数时,返回true,否则返回false

var condion = R.equals(3);

var r1 = R.all(condion,[3,3,3,3]);
var r2 = R.all(condion,[3,3,2,3]);
console.log(r1,r2);//true false

any:只要有一个成员满足条件,就返回true。

console.log(R.any(condion,[1,2,3,4]));//true

none:没有成员满足条件时,返回true。

console.log(R.none(condion,[1,2,5,4]));//true

数组的截取和添加

head:返回数组的第一个成员。

var fisrt =  R.head(['fi', 'fo', 'fum']) // 'fi'
console.log(fisrt);
var fisrt =  R.head([])  // undefined
console.log(fisrt);
var fisrt =  R.head('abc') // 'a'
console.log(fisrt);
var fisrt =  R.head('') // ''
console.log(fisrt);

last 返回数组的最后一个成员

tail:返回第一个成员以外的所有成员组成的新数组。

console.log(R.tail([1,2,4])); //[ 2, 4 ]

init:返回最后一个成员以外的所有成员组成的新数组。

console.log(R.init([1,2,4])); //[ 1,2 ]

nth:取出指定下标的成员。

var number = R.nth(2)([100,200,300,500]);
console.log(number);//300

take:取出前 n 个成员。

var number = R.take(2)([100,200,300,500]);
console.log(number);//[ 100, 200 ]

takeLast:取出后 n 个成员。

var number = R.takeLast(2)([100,200,300,500]);
console.log(number);//[ 300, 500 ]

slice:从起始位置(包括)开始,到结束位置(不包括)为止,从原数组截取出一个新数组。

R.slice(1, 3)(['a', 'b', 'c', 'd']) // ['b', 'c']
R.slice(1, Infinity)(['a', 'b', 'c', 'd']) // ['b', 'c', 'd']
R.slice(0, -1)(['a', 'b', 'c', 'd']) // ['a', 'b', 'c']
R.slice(-3, -1)(['a', 'b', 'c', 'd']) // ['b', 'c']
R.slice(0, 3)('ramda') // 'ram'

remove:移除开始位置后的n个成员。

R.remove(2, 3)([1,2,3,4,5,6,7,8]) // [1,2,6,7,8]

insert:在指定位置插入给定值。

R.insert(2, 'x')([1,2,3,4]) // [1,2,'x',3,4]

insertAll:在指定位置,插入另一个数组的所有成员。

R.insertAll(2,['x','y','z'])([1,2,3,4]) // [1,2,'x','y','z',3,4]

prepend:在数组头部插入一个成员

R.prepend('fee')(['fi', 'fo', 'fum'])
// ['fee', 'fi', 'fo', 'fum']

append:在数组尾部追加新的成员。

R.append('tests')(['write', 'more']) // ['write', 'more', 'tests']

intersperse:在数组成员之间插入表示分隔的成员。

R.intersperse('n')(['ba', 'a', 'a'])
// ['ba', 'n', 'a', 'n', 'a']

join:将数组合并成一个字符串,并在成员之间插入分隔符。

R.join('|')([1, 2, 3]) // '1|2|3'

数组的过滤

  • filter 过滤出符合条件的成员
  • reject 过滤出不满足条件的成员
  • takeWhile 当满足条件时,拿走前面的所有成员,后面的舍弃
  • dropWhile 当不满足条件的时候,舍弃前面的,取后面所有的成员
  • without 返回指定值以外的成员
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,226评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 一个人的信仰值多少钱? 流传的思维 “钱就是万能的啊,如果你觉得有些事情是钱办不到的,只能说明你的钱不够多” 是不...
    爱吃鱼和莴苣的狗阅读 169评论 0 0
  • 战略层 目标用户 ①对订外卖有刚性需求,无论是否有O2O平台都会订外卖的人群②被优惠折扣吸引而订外卖的人群③基本不...
    哩哩Prancy阅读 13,312评论 0 1
  • ES8 或者说是 ES2017 已经在今年6月底的时候被 TC39 正式发布。 字符串填充 在 String 对象...
    day_day_up阅读 1,023评论 0 0