Rmada文档http://ramdajs.com/docs
Ramada是函数是编程的典范
有两种重要的特点
- Ramda函数参数的特点是 函数第一,数据第二(function first,data last)。也就是说 函数排在前面,data排在后面
- Ramda函数都是柯里化curried的,也就是说所有多参数的函数都可以单参数调用。
引入ramda
var R = require('ramda');
比较运算
- 大于 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 返回指定值以外的成员