1.0.11 • Published 5 years ago

@keepzen/fp v1.0.11

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

img img img

id: (any)=>any

The idempotent function.

Parameters

  • v any

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

  • fun Function This is the function whos parameters you want to bind.
  • args *any* The values you bind to the parameters of fun.

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

  • fns Function 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

  • method Function 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

  • v any
  • $1 Object (optional, default {})
    • $1.freeze (optional, default false)

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

  • value any

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 v you want to pipe to other function.

    So pipe(a).valueOf() === a is always true:

    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.

    fun is a function, args are the rest arguments you want pipe to fun.

    • If args do not included placeholder _, fun will be called as fun(...[v,...args]).

    • If args included one and only one placeholder _, pipable.valueOf() will instead of the placehoder, and fun will be called as fun(...args).

  • pipable.map(fun,...args) : pipable.map is the alias of pipable.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 to fun.
    • when pipeable.valueOf() is not a promise, fun will been skiped and return copy of pipable.

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

  • fun Function :~(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

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

  • predicate Function : (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

  • compare Function :~(a,b)=>Boolean~ (optional, default (a,b)=>a-b)
  • $1 Object (optional, default {})
    • $1.asc (optional, default true)

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

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

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

  • fun Function : (element[,index,array])=>boolean
  • iteratable **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

  • fun Function : (element[,index,array])=>boolean
  • iterable **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 .

1.0.11

5 years ago

1.0.10

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago

0.1.3

5 years ago

0.1.2

5 years ago

0.1.1

6 years ago

0.1.0

6 years ago