@keepzen/fp v1.0.11
id: (any)=>any
The idempotent function.
Parameters
vany
Returns any the parameter v.
unary: (fun)=>Function
Convert fun to an unary function.
Parameters
fun
Returns Function
binding: (fun,...args)=>Function
Biding function fun with arguments fellow it.
Parameters
funFunction This is the function whos parameters you want to bind.args…*any* The values you bind to the parameters offun.
Return Function.
The length of return function is fun.length - args.length,
if args are all normal values, when args includes placeholder _,
the length will add the count of placeholders.
Examples
const binding = require('./binding');
const _ = binding.placeHolder;
const fn = (a, b, c, d) => a + b + c + d;
test("binding()", () => {
let bindFn = binding(fn, "1", _, "3");
expect(typeof bindFn).toBe('function');
expect(bindFn.length).toBe(fn.length - 2);
expect(bindFn(2, "a")).toBe('123a');
let bindFn2 = binding(bindFn, _, "a");
expect(bindFn2(2)).toBe(bindFn(2, "a"));
let z = jest.fn(fn);
let bindFn3 = binding(z, 1, 2, 3, 4, 5);
expect(bindFn3.length).toBe(0);
expect(bindFn3()).toBe(1 + 2 + 3 + 4);
expect(z).toHaveBeenCalledWith(1, 2, 3, 4, 5);
console.log(bindFn2.toString());
})bindidng.placeHolder: Symbol
The place holder that can be use zero or manny times as element of args in binding(fun,...args).
compose: (...funs)=>Function
Compose functions fns to make a new function.
Parameters
fnsFunction The functions you want to compose them to be one.
Returns Function
Examples
const { compose, pipe } = require('./compose');
const g = jest.fn((a, b) => a + b);
const f = jest.fn(c => c + 1);
test('compose(f,g)', () => {
const z = compose(f, g);
expect(typeof z).toBe('function');
expect(z.length).toBe(g.length);
expect(z(1, 2, 3)).toBe(1 + 2 + 1);
expect(g).toHaveBeenCalledWith(1, 2, 3);
expect(f).toHaveBeenCalledWith(3);
})pipe: (...funs)=>Function
pipe is like the compose but reverse the execute order.
It is differtne with pipable. pipable make a functor.
Parameters
fns…Function
Returns Function
Examples
const { compose, pipe } = require('./compose');
const g = jest.fn((a, b) => a + b);
const f = jest.fn(c => c + 1);
test('compose(f,g)', () => {
const z = compose(f, g);
expect(typeof z).toBe('function');
expect(z.length).toBe(g.length);
expect(z(1, 2, 3)).toBe(1 + 2 + 1);
expect(g).toHaveBeenCalledWith(1, 2, 3);
expect(f).toHaveBeenCalledWith(3);
})
test('pipe(g,f)', () => {
const z = pipe(g, f);
expect(typeof z).toBe('function');
expect(z.length).toBe(g.length);
expect(z(1, 2, 3)).toBe(1 + 2 + 1);
expect(g).toHaveBeenCalledWith(1, 2, 3);
expect(f).toHaveBeenCalledWith(3);
console.log(z.name);
})m2f: (method)=>Function
Convert a method to a function.
If you have a function fn you can attch it to a object obj like
obj.fn=fn, so the this in fn now is obj.
But how do you do if you want use a method as a function? Like sort arrays with a fixed way?
m2f is use to help you for this.
Parameters
methodFunction The method you want covert to a function.
Returns Function.
The return function do same as md, but add this as the first parameter.
Examples
const m2f = require('./m2f');
test('metholdToFunction()', () => {
const join = m2f([].join);
expect(typeof join).toBe(`function`);
expect(join([1, 2], ",")).toBe([1, 2].join(","));
expect(join.length).toBe([].join.length + 1);
})deepCopy: (any[,{freeze}])=>any
Deep copy the value.
Parameters
vany$1Object (optional, default{})$1.freeze(optional, defaultfalse)
Returns a new deep Copyed Object.
Examples
const deepCopy = require('./deep-copy');
test('deepCopy()', () => {
expect(deepCopy(1)).toBe(1);
expect(deepCopy(true)).toBe(true);
let fn = jest.fn();
expect(deepCopy(fn)).toBe(fn);
let a = [];
a.push(1, 3);
a.push(a)
let aCopy = deepCopy(a);
expect(aCopy[2]).toBe(aCopy);
let b = { a, v: 1 };
a.push(b);
let bCopy = deepCopy(b);
console.log(bCopy);
expect(bCopy === bCopy.a[3]).toBe(true);
})constant: (any)=>()=>any
Give a value, get a function, which always return freezen deep copy of the given value.
If you just want get a immutable copy, just use
deepCopy(value,{freeze:true}).
Parameters
valueany
Returns Function : ()=>freezenDeepCopyOfValue
Pipable
Note:This is the package of @keepzen/pipe.js, and in package of @keepzen/fp rexport
as Pipable. So the snippets in this section, Pipe, pipe, from, and -
are all in namespace of Pipable.
Make a pipable
Pipable is a object, which have a method named .pipe(fun,...args).
You can get a new pipable object as fellow ways:
const {
Pipe,
pipe,
from,
_
} = require('./pipe.js')
test('make pipable', () => {
const properties = ['valueOf', 'pipe', 'map', "promise_rescue"].sort();
const keys = Object.keys.bind(Object);
expect(keys(Pipe(1)).sort()).toMatchObject(properties);
expect(keys(pipe(1)).sort()).toMatchObject(properties);
expect(keys(from(1)).sort()).toMatchObject(properties);
expect(keys(from(1).pipe(a => a + 1)).sort()).toMatchObject(properties);
})As then snippet showed, a pipable object have methods as fellow:
pipable.valueOf():Get the
vyou want to pipe to other function.So
pipe(a).valueOf() === ais alwaystrue:test('pipe(any).valueOf() == any', () => { expect(pipe(1).valueOf() == 1).toBe(true) expect(pipe("hello").valueOf() == "hello").toBe(true); expect(pipe(true).valueOf() == true).toBe(true); expect(pipe(false).valueOf() == false).toBe(true); let str = new String('Hello'); expect(pipe(str).valueOf() == str).toBe(true); expect(pipe(null).valueOf() == null).toBe(true); expect(pipe(undefined).valueOf() == undefined).toBe(true); let a = { hello: "a" }; expect(pipe(a).valueOf() == a).toBe(true) })
If a is primary type but neither null nor undefined then pipe(a) == a
is true.
test('pipe(primary) == primary', () => {
expect(pipe(1) == 1).toBe(true)
expect(pipe("hello") == "hello").toBe(true);
expect(pipe(true) == true).toBe(true);
expect(pipe(false) == false).toBe(true);
let str = new String('Hello')
expect(pipe(str) == str).toBe(false);
expect(pipe(null) == null).toBe(false);
expect(pipe(undefined) == undefined).toBe(false);
let a = { hello: "a" };
expect(pipe(a) == a).toBe(false);
})pipable.pipe(fun,...args): Return a pipable object.funis a function,argsare the rest arguments you want pipe tofun.If
argsdo not included placeholder_,funwill be called asfun(...[v,...args]).If
argsincluded one and only one placeholder_,pipable.valueOf()will instead of the placehoder, andfunwill be called asfun(...args).
pipable.map(fun,...args):pipable.mapis the alias ofpipable.pipe.pipable.promise_rescue(fun,...args): return a new pipable object.- when the
pipable.vlaueOf()is a promise and the promise is reject, the reject reason will pipe tofun. - when
pipeable.valueOf()is not a promise,funwill been skiped and return copy ofpipable.
- when the
Use placeholder set which argument of fun take the piped value
test('pipe with placeholder', () => {
let fn = jest.fn((a, b, c) => a + b + c);
let z = pipe('a').pipe(fn, 'b', 'c');
expect(fn).not.toHaveBeenCalled();
expect(z == 'abc').toBe(true);
expect(fn).toBeCalledWith('a', 'b', 'c');
z = pipe("2").pipe(fn, "1", _, "3");
expect(z == '123').toBe(true);
expect(fn).toBeCalledWith('1', '2', '3');
z = pipe('e').pipe(fn, 'a', 'b', 'c', 'd', _);
expect(z == 'abc');
expect(fn).toHaveBeenLastCalledWith('a', 'b', 'c', 'd', 'e');
})pipable.pipe(fun,...args) keep pipable object immutable.
pipable.pipe(fn,...args) will return a new pipable object,don't change the old one.
test('pipable is independ', () => {
let a = 1;
let fn1 = jest.fn(a => a + 1);
let fn2 = jest.fn((b, c) => b + c);
let pipable0 = pipe(a);
let pipable1 = pipable0.pipe(fn1);
expect(pipable1 == a + 1).toBe(true);
expect(pipable0.valueOf()).toBe(a);
let pipable2 = pipable1.pipe(fn2, 'c');
expect(pipable2 == '2c').toBe(true);
expect(pipable1.valueOf()).toBe(a + 1);
})pipable.pipe(fn,...args) is lazy
Call pipeable.pipe(fn,...args) do not call fn,
but pipable.valueOf() will call the fn if there have one.
As fellow show:
test(`pipable is layze`, () => {
const fn = jest.fn(a => a + 1);
let pipable0 = pipe(1);
let ret = pipable0.pipe(fn).pipe(fn).pipe(fn);
expect(fn).not.toHaveBeenCalled();
expect(ret.valueOf()).toBe(1 + 1 + 1 + 1);
expect(fn.mock.calls).toMatchObject([[1], [2], [3]]);
})pipable<Promise>.pipe(fn,...args)
If the value of a pipable is a Promise,
pipable.pipe(fn) pipe the resolve value of the promise to fn,
and return a new promise pipable.
Examaples
test('pipe promise resolve ', (done) => {
let a = from(Promise.resolve(1));
expect(a.valueOf()).toBeInstanceOf(Promise);
let fn = jest.fn(a => a + 1);
let ret = a.pipe(fn).
promise_rescue(fn).//skip
pipe(fn).valueOf();
expect(ret).toBeInstanceOf(Promise);
ret.then(() => {
expect(fn.mock.calls).toMatchObject([[1], [2]]);
done();
});
})pipable<Promise>.promise_rescue:
Return a new pipable.
If value of pipable<Promise> is reject, this method can rescue from the error.
test('pipe promise reject', (done) => {
let a = from(Promise.reject('hello'));
let fn1 = jest.fn(a => 'fn1');
let fn2 = jest.fn(a => 'fn2');
let fn3 = jest.fn(a => "fn3");
let promise = a.pipe(fn1).//skip
promise_rescue(fn2).//call
pipe(fn3).valueOf();
expect(promise).toBeInstanceOf(Promise);
promise.then(
(a) => {
expect(fn1).not.toHaveBeenCalled();
expect(fn2).toHaveBeenCalledWith('hello');
expect(fn3).toHaveBeenCalledWith('fn2');
expect(a).toBe('fn3');
done();
},
(error) => {
console.error(error);
expect('not run to here').toBe('but it is here');
}
)
})not: not(fn)=>Function
Negative fun.
If fun is a predicater, return a new negative predicater.
If fun is a compare function, return the negative compare function.
Parameters
funFunction :~(v,…args)=>Boolean|Number~
Returns Function other_fun: (v,...args)=>Boolean|Number
Examples
const not = require('./not');
test('not(p)', () => {
let p = n => n % 2 == 0;
expect(not(p)(2)).toBe(!p(2));
expect(not(p)(1)).toBe(!p(1));
expect(not((a, b) => a - b)(1, 2)).toBe(2 - 1);
})selectWith: predicate=>array=>Array
select some array with predicate.
Support there is an array include value v, and predicate(v) is true,
then select(array) will include v.
Parameters
predicateFunction (v,index)=>Boolean;
Returns Function select: (array)=>array
Examples
let array = [1, 2, 3, 4];
let arrayb = [5, 6, 7, 8];
const isOlder = d => d % 2 == 0;
test('selectWith(fun,array)', () => {
const selectOld = selectWith(isOlder);
expect(selectOld(array)).toMatchObject([2, 4]);
expect(selectOld(arrayb)).toMatchObject([6, 8]);rejectWith: predicate=>array=>Array
Reject some array with predicate.
Support there is an array include value v,and predicate(v) is true,
then reject(array) will **not** include v.
Parameters
predicateFunction : (v,index)=>Boolean;
Returns Function reject:(array)=>array
test('rejectWith(isOlder)', () => {
const rejectOlder = rejectWith(isOlder);
expect(rejectOlder(array)).toMatchObject([1, 3]);
expect(rejectOlder(arrayb)).toMatchObject([5, 7]);
})orderWith: ~(compare,{asc})=>array=>Array
Order a array with a compare function.
When asc is true, sort value in ascending order else in descending.
For compare(a,b), in asc order,
if you want a in front of b, return a negative number;
if your want b in front of a return a positive number;
else you do not care which first return zero.
Parameters
compareFunction :~(a,b)=>Boolean~ (optional, default(a,b)=>a-b)$1Object (optional, default{})$1.asc(optional, defaulttrue)
Returns Function order:(array)=>array
Examples
test('orderWith(fun)', () => {
let sortByZ = orderWith((a, b) => a.z - b.z);
let array = [{ a: 1, z: 2 }, { a: 2, z: 1 }, { a: 3, z: -1 }];
let first = array[0];
let ret = sortByZ(array);
expect(ret).toMatchObject([{ a: 3, z: -1 }, { a: 2, z: 1 }, { a: 1, z: 2 }]);
expect(ret[2]).toBe(first)
expect(array[0]).toBe(first);
});
test('orderWith(fun,{asc=false})', () => {
let sortByZ = orderWith((a, b) => a.z - b.z, { asc: false });
let array = [{ a: 1, z: 2 }, { a: 2, z: 1 }, { a: 3, z: -1 }];
let ret = sortByZ(array);
expect(ret).toMatchObject(array);
expect(ret).not.toBe(array);
expect(ret[0]).toBe(array[0]);
});reverse: (array)=>Array
Get a reversed new the array from array.
Parameters
arrayArray
Returns Array
Examples
test('reverse(array)', () => {
let array = [1, 2, 3, 4];
expect(reverse(array)).toMatchObject([4, 3, 2, 1]);
expect(array).toMatchObject([1, 2, 3, 4]);
})zip: (aIterable,arrayLikly)=>Array<Array(2)>
Zip arrays a1 and a2 to an array of array.
Parameters
Returns Array Array<Array(2)>
Examples
test('zip(a1,a2)', () => {
const a1 = [1, 2, 3, 4];
const a2 = ['one', 'two', 'three'];
const ret1 = zip(a1, a2);
expect(ret1).toMatchObject([[1, 'one'], [2, 'two'], [3, 'three'], [4, undefined]]);
expect(zip(a2, a1)).toMatchObject([['one', 1], ['two', 2], ['three', 3]]);
})every: (fun,iterable)=>boolean
Check is every element in iteratble satisfy contiontion fun.
If iterable is empty, return true. See more at
here;
Parameters
funFunction :~(element,index,array)~iterable**Iterable**
Returns **any** boolean
Examples
test('every(funp,arrayLikly)', () => {
expect(every(positive, [1, 2, 3, 4])).toBe(true);
expect(every(positive, [1, 2, -1, 3, 4])).toBe(false)
expect(every(positive, [])).toBe(true)
})all: (fun,iterable)=>boolean
Check is all element in iteratble satisfy contiontion fun.
This is similarity as every but if iterable is empty, return false.
Parameters
funFunction :(element[,index,array])=>booleaniteratable**Iterable**
Examples
const positive = a => a > 0;
test('all(funp,arrayLike)', () => {
expect(all(positive, [1, 2, 3, 4])).toBe(true);
expect(all(positive, [1, 2, -1, 3, 4])).toBe(false)
expect(all(positive, [])).toBe(false)
})every: (fun,iterable)=>boolean
Similarity as , but if iterable is empty, return true.
any: (fun,iterable)=>boolean
Check is some element in iterable satisfy contiontion fun.
Parameters
funFunction :(element[,index,array])=>booleaniterable**Iterable**
Examples
test('any(funp,arrayLikly)', () => {
expect(any(positive, [-1, -2, -3, 4])).toBe(true);
expect(any(positive, [-1, -2, -3, -4])).toBe(false);
expect(any(positive, [])).toBe(false);
expect(any(positive, [0])).toBe(false);
expect(any(positive, [+0])).toBe(false);
expect(any(positive, [-0])).toBe(false);
})some: (fun,iterable)=>boaolean
Alias of .