2019-09-16 18:20:42 +00:00
|
|
|
tk-functional
|
|
|
|
=============
|
|
|
|
|
2019-09-22 21:05:33 +00:00
|
|
|
[![pipeline status](https://gitlab.com/thunderk/tk-functional/badges/master/pipeline.svg)](https://gitlab.com/thunderk/tk-functional/commits/master)
|
|
|
|
[![coverage report](https://gitlab.com/thunderk/tk-functional/badges/master/coverage.svg)](https://gitlab.com/thunderk/tk-functional/commits/master)
|
|
|
|
[![npm version](https://img.shields.io/npm/v/tk-functional.svg)](https://npmjs.com/tk-functional)
|
|
|
|
[![npm size](https://img.shields.io/bundlephobia/min/tk-functional.svg)](https://bundlephobia.com/result?p=tk-functional)
|
|
|
|
|
2019-09-16 18:20:42 +00:00
|
|
|
About
|
|
|
|
-----
|
|
|
|
|
|
|
|
Provides some common helpers for functional-style programming.
|
|
|
|
|
|
|
|
Typescript definitions are included.
|
|
|
|
|
2019-09-22 21:05:33 +00:00
|
|
|
Issues can be reported on [GitLab](https://gitlab.com/thunderk/tk-functional/issues).
|
2019-09-16 18:20:42 +00:00
|
|
|
|
|
|
|
Functions
|
|
|
|
---------
|
|
|
|
|
2019-09-29 22:13:03 +00:00
|
|
|
**always** and **never** return true and false respectively
|
2019-09-16 18:20:42 +00:00
|
|
|
|
|
|
|
```typescript
|
2019-09-29 22:13:03 +00:00
|
|
|
always() // => true
|
|
|
|
never() // => false
|
|
|
|
```
|
|
|
|
|
2019-10-17 21:26:50 +00:00
|
|
|
**and**, **or** and **not** allow to combine or negate predicates
|
2019-09-29 22:13:03 +00:00
|
|
|
|
|
|
|
```typescript
|
|
|
|
const a = and((x: number) => x > 2, (x: number) => x < 5);
|
|
|
|
a(2) // => false
|
|
|
|
a(3) // => true
|
|
|
|
a(4) // => true
|
|
|
|
a(5) // => false
|
|
|
|
const o = or((x: number) => x < 2, (x: number) => x > 3);
|
|
|
|
o(1) // => true
|
|
|
|
o(2) // => false
|
|
|
|
o(3) // => false
|
|
|
|
o(4) // => true
|
2019-10-17 21:26:50 +00:00
|
|
|
const n = not((x: number) => x == 1);
|
|
|
|
n(0) // => true
|
|
|
|
n(1) // => false
|
|
|
|
n(2) // => true
|
2019-09-29 22:13:03 +00:00
|
|
|
```
|
|
|
|
|
2019-10-22 20:07:18 +00:00
|
|
|
**at** gets an array's item by position:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
const getthird = at(2);
|
|
|
|
getthird([2, 4, 8, 16]); // => 8
|
|
|
|
getthird([2, 4]); // => undefined
|
|
|
|
const getsecondlast = at(-2);
|
|
|
|
getsecondlast([1, 2, 3, 4]); // => 3
|
|
|
|
getsecondlast([1]); // => undefined
|
|
|
|
```
|
|
|
|
|
2019-09-29 22:13:03 +00:00
|
|
|
**attr** gets an object's attribute:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
const getx = attr("x");
|
|
|
|
getx({x: 3}); // => 3
|
|
|
|
```
|
|
|
|
|
|
|
|
**bool** checks for boolean equivalence (in a broader sense than !(!(val))):
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
bool(undefined); // => false
|
|
|
|
bool(null); // => false
|
|
|
|
|
|
|
|
bool(-1); // => true
|
|
|
|
bool(0); // => false
|
|
|
|
bool(1); // => true
|
|
|
|
|
|
|
|
bool(""); // => false
|
|
|
|
bool(" "); // => true
|
|
|
|
bool("abc"); // => true
|
|
|
|
|
|
|
|
bool([]); // => false
|
|
|
|
bool([1, 2, 3]); // => true
|
|
|
|
|
|
|
|
bool({}); // => false
|
|
|
|
bool({x: 1}); // => true
|
|
|
|
```
|
|
|
|
|
|
|
|
**cmp** simplifies the use of array sorting:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
[8, 3, 5].sort(cmp()) // => [3, 5, 8]
|
|
|
|
[8, 3, 5].sort(cmp({ reverse: true })) // => [8, 5, 3]
|
|
|
|
[-2, 8, -7].sort(cmp({ key: Math.abs })) // => [-2, -7, 8]
|
2019-09-16 18:20:42 +00:00
|
|
|
```
|
|
|
|
|
2019-10-22 20:07:18 +00:00
|
|
|
**first** and **last** return the first or last item of an array:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
first([1, 2, 3]) // => 1
|
|
|
|
first([]) // => undefined
|
|
|
|
last([1, 2, 3]) // => 3
|
|
|
|
last([]) // => undefined
|
|
|
|
```
|
|
|
|
|
2019-09-16 18:20:42 +00:00
|
|
|
**identity** returns its argument untouched:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
a === identity(a) // => true
|
|
|
|
```
|
|
|
|
|
2019-10-17 20:51:42 +00:00
|
|
|
**is** and **isinstance** checks for strict equality and inheritance:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
const f = is(8);
|
|
|
|
f(8) // => true
|
|
|
|
f(5 + 3) // => true
|
|
|
|
f("8") // => false
|
|
|
|
f(null) // => false
|
|
|
|
|
|
|
|
class A { }
|
|
|
|
class A1 extends A { }
|
|
|
|
class A2 extends A { }
|
|
|
|
class B { }
|
|
|
|
const f: any[] = [5, null, undefined, new A, new A1, new B, new A2];
|
|
|
|
const result: A[] = f.filter(isinstance(A)); // => [f[3], f[4], f[6]]
|
|
|
|
```
|
|
|
|
|
2019-09-29 22:13:03 +00:00
|
|
|
**nn**, **nu** and **nnu** checks at run-time for null or undefined:
|
2019-09-24 21:39:04 +00:00
|
|
|
|
|
|
|
```typescript
|
2019-09-29 22:13:03 +00:00
|
|
|
nn(undefined) // => undefined
|
|
|
|
nn(null) // => Error
|
|
|
|
nn(1) // => 1
|
|
|
|
|
|
|
|
nu(undefined) // => Error
|
|
|
|
nu(null) // => null
|
|
|
|
nu(1) // => 1
|
|
|
|
|
|
|
|
nnu(undefined) // => Error
|
|
|
|
nnu(null) // => Error
|
|
|
|
nnu(1) // => 1
|
|
|
|
```
|
|
|
|
|
|
|
|
**nop** does nothing (useful for some callbacks):
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
new ConstructorWithMandatoryCallback(nop)
|
2019-09-24 21:39:04 +00:00
|
|
|
```
|
|
|
|
|
2019-09-16 18:20:42 +00:00
|
|
|
**partial** applies a partial configuration object as first argument of compatible functions:
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
const sum = (args: {a: number, b: number}) => args.a + args.b
|
|
|
|
const plus1 = partial({a: 1}, sum);
|
|
|
|
plus1({b: 8}) // => 9
|
|
|
|
```
|
|
|
|
|
2019-09-29 22:13:03 +00:00
|
|
|
**pipe** chains two functions as one:
|
2019-09-16 18:20:42 +00:00
|
|
|
|
|
|
|
```typescript
|
2019-09-29 22:13:03 +00:00
|
|
|
const f = pipe((x: number) => x * 2, (x: number) => x + 1);
|
|
|
|
f(3) // => 7 ((3 * 2) + 1)
|
2019-09-16 18:20:42 +00:00
|
|
|
```
|