UNPKG

566 kBMarkdownView Raw
1# Rambda
2
3`Rambda` is smaller and faster alternative to the popular functional programming library **Ramda**. - [Documentation](https://selfrefactor.github.io/rambda/#/)
4
5[![CircleCI](https://circleci.com/gh/selfrefactor/rambda/tree/master.svg?style=svg)](https://circleci.com/gh/selfrefactor/rambda/tree/master)
6[![codecov](https://codecov.io/gh/selfrefactor/rambda/branch/master/graph/badge.svg)](https://codecov.io/gh/selfrefactor/rambda)
7[![dependencies Status](https://david-dm.org/selfrefactor/rambda/status.svg)](https://david-dm.org/selfrefactor/rambda)
8![Commit activity](https://img.shields.io/github/commit-activity/y/selfrefactor/rambda)
9![All contributors](https://img.shields.io/github/contributors/selfrefactor/rambda)
10![Library size](https://img.shields.io/bundlephobia/minzip/rambda)
11
12## ➤ Example use
13
14```javascript
15import { compose, map, filter } from 'rambda'
16
17const result = compose(
18 map(x => x * 2),
19 filter(x => x > 2)
20)([1, 2, 3, 4])
21// => [6, 8]
22```
23
24You can test this example in <a href="https://rambda.now.sh?const%20result%20%3D%20R.compose(%0A%20%20R.map(x%20%3D%3E%20x%20*%202)%2C%0A%20%20R.filter(x%20%3D%3E%20x%20%3E%202)%0A)(%5B1%2C%202%2C%203%2C%204%5D)%0A%0A%2F%2F%20%3D%3E%20%5B6%2C%208%5D">Rambda's REPL</a>
25
26* [Install](#install)
27* [Differences between Rambda and Ramda](#differences-between-rambda-and-ramda)
28* [API](#api)
29* [Changelog](#changelog)
30
31[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-example-use)
32
33## ➤ Rambda's advantages
34
35### Typescript included
36
37Typescript definitions are included in the library, in comparison to **Ramda**, where you need to additionally install `@types/ramda`.
38
39Still, you need to be aware that functional programming features in `Typescript` are in development, which means that using **R.compose/R.pipe** can be problematic.
40
41### Smaller size
42
43The size of a library affects not only the build bundle size but also the dev bundle size and build time. This is important advantage, expecially for big projects.
44
45### Tree-shaking
46
47Currently **Rambda** is more tree-shakable than **Ramda** - proven in the following [repo](https://github.com/selfrefactor/rambda-tree-shaking).
48
49The repo holds two `Angular9` applications: one with small example code of *Ramda* and the other - same code but with *Rambda* as import library.
50
51The test shows that **Rambda** bundle size is **2.03 MB** less than its **Ramda** counterpart.
52
53There is also [Webpack/Rollup/Parcel/Esbuild tree-shaking example including several libraries](https://github.com/mischnic/tree-shaking-example) including `Ramda`, `Rambda` and `Rambdax`.
54
55> actually tree-shaking is the initial reason for creation of `Rambda`
56
57### Dot notation for `R.path`, `R.paths`, `R.assocPath` and `R.lensPath`
58
59Standard usage of `R.path` is `R.path(['a', 'b'], {a: {b: 1} })`.
60
61In **Rambda** you have the choice to use dot notation(which is arguably more readable):
62
63```
64R.path('a.b', {a: {b: 1} })
65```
66
67### Comma notation for `R.pick` and `R.omit`
68
69Similar to dot notation, but the separator is comma(`,`) instead of dot(`.`).
70
71```
72R.pick('a,b', {a: 1 , b: 2, c: 3} })
73// No space allowed between properties
74```
75
76### Speed
77
78**Rambda** is generally more performant than `Ramda` as the [benchmarks](#benchmarks) can prove that.
79
80### Support
81
82Most of the valid issues are fixed within 2-3 days.
83
84Closing the issue is usually accompanied by publishing a new patch version of `Rambda` to NPM.
85
86[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-rambdas-advantages)
87
88## ➤ Missing Ramda methods
89
90<details>
91<summary>
92 Click to see the full list of 90 Ramda methods not implemented in Rambda
93</summary>
94
95- __
96- addIndex
97- ap
98- aperture
99- apply
100- applyTo
101- ascend
102- binary
103- bind
104- call
105- comparator
106- composeK
107- composeP
108- composeWith
109- construct
110- constructN
111- contains
112- countBy
113- descend
114- differenceWith
115- dissocPath
116- empty
117- eqBy
118- forEachObjIndexed
119- gt
120- gte
121- hasIn
122- innerJoin
123- insert
124- insertAll
125- into
126- invert
127- invertObj
128- invoker
129- juxt
130- keysIn
131- lift
132- liftN
133- lt
134- lte
135- mapAccum
136- mapAccumRight
137- mapObjIndexed
138- memoizeWith
139- mergeDeepLeft
140- mergeDeepWith
141- mergeDeepWithKey
142- mergeRight
143- mergeWith
144- mergeWithKey
145- nAry
146- nthArg
147- o
148- objOf
149- otherwise
150- pair
151- partialRight
152- pathSatisfies
153- pickBy
154- pipeK
155- pipeP
156- pipeWith
157- project
158- propSatisfies
159- reduceBy
160- reduceRight
161- reduceWhile
162- reduced
163- remove
164- scan
165- sequence
166- sortWith
167- symmetricDifferenceWith
168- andThen
169- toPairsIn
170- transduce
171- traverse
172- unapply
173- unary
174- uncurryN
175- unfold
176- unionWith
177- uniqBy
178- unnest
179- until
180- useWith
181- valuesIn
182- xprod
183- thunkify
184- default
185
186</details>
187
188[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-missing-ramda-methods)
189
190## ➤ Install
191
192- **yarn add rambda**
193
194- For UMD usage either use `./dist/rambda.umd.js` or the following CDN link:
195
196```
197https://unpkg.com/rambda@CURRENT_VERSION/dist/rambda.umd.js
198```
199
200- with deno
201
202```
203import {compose, add} from 'https://raw.githubusercontent.com/selfrefactor/rambda/master/dist/rambda.esm.js'
204```
205
206[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-install)
207
208## Differences between Rambda and Ramda
209
210- Rambda's **type** detects async functions and unresolved `Promises`. The returned values are `'Async'` and `'Promise'`.
211
212- Rambda's **type** handles *NaN* input, in which case it returns `NaN`.
213
214- Rambda's **forEach** can iterate over objects not only arrays.
215
216- Rambda's **map**, **filter**, **partition** when they iterate over objects, they pass property and input object as predicate's argument.
217
218- Rambda's **filter** returns empty array with bad input(`null` or `undefined`), while Ramda throws.
219
220- Ramda's **clamp** work with strings, while Rambda's method work only with numbers.
221
222- Error handling, when wrong inputs are provided, may not be the same. This difference will be better documented once all brute force tests are completed.
223
224- Typescript definitions between `rambda` and `@types/ramda` may vary.
225
226> If you need more **Ramda** methods in **Rambda**, you may either submit a `PR` or check the extended version of **Rambda** - [Rambdax](https://github.com/selfrefactor/rambdax). In case of the former, you may want to consult with [Rambda contribution guidelines.](CONTRIBUTING.md)
227
228[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-differences-between-rambda-and-ramda)
229
230## ➤ Benchmarks
231
232<details>
233
234<summary>
235Click to expand all benchmark results
236
237There are methods which are benchmarked only with `Ramda` and `Rambda`(i.e. no `Lodash`).
238
239Note that some of these methods, are called with and without curring. This is done in order to give more detailed performance feedback.
240
241The benchmarks results are produced from latest versions of *Rambda*, *Lodash*(4.17.19) and *Ramda*(0.27.0).
242
243</summary>
244
245method | Rambda | Ramda | Lodash
246--- |--- | --- | ---
247 *add* | 96.25% slower | 96.24% slower | 🚀 Fastest
248 *adjust* | 🚀 Fastest | 5.52% slower | 🔳
249 *all* | 🚀 Fastest | 94.95% slower | 🔳
250 *allPass* | 🚀 Fastest | 98.95% slower | 🔳
251 *any* | 🚀 Fastest | 98.18% slower | 6.18% slower
252 *anyPass* | 🚀 Fastest | 99.09% slower | 🔳
253 *append* | 🚀 Fastest | 84.09% slower | 🔳
254 *applySpec* | 🚀 Fastest | 75.73% slower | 🔳
255 *assoc* | 87.98% slower | 57.39% slower | 🚀 Fastest
256 *clone* | 🚀 Fastest | 96.03% slower | 91.75% slower
257 *compose* | 🚀 Fastest | 96.45% slower | 77.83% slower
258 *converge* | 49.12% slower | 🚀 Fastest | 🔳
259 *curry* | 🚀 Fastest | 34.9% slower | 🔳
260 *curryN* | 63.32% slower | 🚀 Fastest | 🔳
261 *defaultTo* | 🚀 Fastest | 50.3% slower | 🔳
262 *drop* | 🚀 Fastest | 97.45% slower | 🔳
263 *dropLast* | 🚀 Fastest | 97.07% slower | 🔳
264 *equals* | 72.11% slower | 79.48% slower | 🚀 Fastest
265 *filter* | 🚀 Fastest | 94.74% slower | 58.18% slower
266 *find* | 🚀 Fastest | 98.2% slower | 88.96% slower
267 *findIndex* | 🚀 Fastest | 97.97% slower | 79.39% slower
268 *flatten* | 6.56% slower | 95.38% slower | 🚀 Fastest
269 *ifElse* | 🚀 Fastest | 70.97% slower | 🔳
270 *includes* | 🚀 Fastest | 71.7% slower | 🔳
271 *indexOf* | 🚀 Fastest | 84.08% slower | 7.86% slower
272 *init* | 94.42% slower | 97.55% slower | 🚀 Fastest
273 *is* | 🚀 Fastest | 11.72% slower | 🔳
274 *isEmpty* | 51.68% slower | 93.82% slower | 🚀 Fastest
275 *last* | 🚀 Fastest | 99.64% slower | 1.05% slower
276 *lastIndexOf* | 🚀 Fastest | 42.38% slower | 🔳
277 *map* | 🚀 Fastest | 69.63% slower | 4.68% slower
278 *match* | 🚀 Fastest | 46.75% slower | 🔳
279 *merge* | 63.55% slower | 🚀 Fastest | 55.25% slower
280 *none* | 🚀 Fastest | 98.22% slower | 🔳
281 *omit* | 🚀 Fastest | 70.66% slower | 97.56% slower
282 *over* | 🚀 Fastest | 50.77% slower | 🔳
283 *path* | 🚀 Fastest | 74.94% slower | 5.72% slower
284 *pick* | 🚀 Fastest | 26.29% slower | 86.82% slower
285 *prop* | 🚀 Fastest | 89.89% slower | 🔳
286 *propEq* | 🚀 Fastest | 95.26% slower | 🔳
287 *range* | 95.17% slower | 90.22% slower | 🚀 Fastest
288 *reduce* | 52.76% slower | 74.02% slower | 🚀 Fastest
289 *repeat* | 85.91% slower | 95.31% slower | 🚀 Fastest
290 *replace* | 0.47% slower | 28.13% slower | 🚀 Fastest
291 *set* | 🚀 Fastest | 36.26% slower | 🔳
292 *sort* | 🚀 Fastest | 63.15% slower | 🔳
293 *sortBy* | 🚀 Fastest | 61.57% slower | 88.88% slower
294 *split* | 🚀 Fastest | 85.34% slower | 33.69% slower
295 *splitEvery* | 🚀 Fastest | 90.18% slower | 🔳
296 *take* | 93.44% slower | 98.04% slower | 🚀 Fastest
297 *takeLast* | 92.61% slower | 98.83% slower | 🚀 Fastest
298 *test* | 🚀 Fastest | 94.42% slower | 🔳
299 *type* | 18.91% slower | 🚀 Fastest | 🔳
300 *uniq* | 98.98% slower | 96.58% slower | 🚀 Fastest
301 *update* | 🚀 Fastest | 38.88% slower | 🔳
302 *view* | 🚀 Fastest | 82.21% slower | 🔳
303
304</details>
305
306[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-benchmarks)
307
308## ➤ Used by
309
310- [WatermelonDB](https://github.com/Nozbe/WatermelonDB)
311
312- [SAP's Cloud SDK](https://github.com/SAP/cloud-sdk)
313
314- [Walmart Canada](https://www.walmart.ca) reported by [w-b-dev](https://github.com/w-b-dev)
315
316- [VSCode Slack intergration](https://github.com/verydanny/vcslack)
317
318- [Webpack PostCSS](https://github.com/sectsect/webpack-postcss)
319
320- [MobX-State-Tree decorators](https://github.com/farwayer/mst-decorators)
321
322- [Mobx decorators](https://github.com/farwayer/mobx-decorators)
323
324[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-used-by)
325
326## API
327
328### add
329
330```typescript
331
332add(a: number, b: number): number
333```
334
335It adds `a` and `b`.
336
337> :boom: It doesn't work with strings, as the inputs are parsed to numbers before calculation.
338
339```javascript
340R.add(2, 3) // => 5
341```
342
343<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.add(2%2C%203)%20%2F%2F%20%3D%3E%20%205">Try this <strong>R.add</strong> example in Rambda REPL</a>
344
345<details>
346
347<summary>All Typescript definitions</summary>
348
349```typescript
350add(a: number, b: number): number;
351add(a: number): (b: number) => number;
352```
353
354</details>
355
356<details>
357
358<summary><strong>R.add</strong> source</summary>
359
360```javascript
361export function add(a, b) {
362 if (arguments.length === 1)
363 return (_b) => add(a, _b);
364
365 return Number(a) + Number(b);
366}
367```
368
369</details>
370
371<details>
372
373<summary><strong>Tests</strong></summary>
374
375```javascript
376import { add } from './add'
377
378test('with number', () => {
379 expect(add(2, 3)).toEqual(5)
380 expect(add(7)(10)).toEqual(17)
381})
382
383test('string is bad input', () => {
384 expect(add('foo', 'bar')).toBeNaN()
385})
386
387test('ramda specs', () => {
388 expect(add('1', '2')).toEqual(3)
389 expect(add(1, '2')).toEqual(3)
390 expect(add(true, false)).toEqual(1)
391 expect(add(null, null)).toEqual(0)
392 expect(add(undefined, undefined)).toEqual(NaN)
393 expect(add(new Date(1), new Date(2))).toEqual(3)
394})
395```
396
397</details>
398
399<details>
400
401<summary><strong>Typescript</strong> test</summary>
402
403```typescript
404import {add} from 'rambda'
405
406describe('R.add', () => {
407 it('happy', () => {
408 const result = add(4, 1)
409
410 result // $ExpectType number
411 })
412 it('curried', () => {
413 const result = add(4)(1)
414
415 result // $ExpectType number
416 })
417})
418```
419
420</details>
421
422[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#add)
423
424### adjust
425
426```typescript
427
428adjust<T>(index: number, replaceFn: (x: T) => T, list: T[]): T[]
429```
430
431It replaces `index` in array `list` with the result of `replaceFn(list[i])`.
432
433```javascript
434R.adjust(
435 0,
436 a => a + 1,
437 [0, 100]
438) // => [1, 100]
439```
440
441<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.adjust(%0A%20%200%2C%0A%20%20a%20%3D%3E%20a%20%2B%201%2C%0A%20%20%5B0%2C%20100%5D%0A)%20%2F%2F%20%3D%3E%20%5B1%2C%20100%5D">Try this <strong>R.adjust</strong> example in Rambda REPL</a>
442
443<details>
444
445<summary>All Typescript definitions</summary>
446
447```typescript
448adjust<T>(index: number, replaceFn: (x: T) => T, list: T[]): T[];
449adjust<T>(index: number, replaceFn: (x: T) => T): (list: T[]) => T[];
450```
451
452</details>
453
454<details>
455
456<summary><strong>R.adjust</strong> source</summary>
457
458```javascript
459import { curry } from './curry'
460
461function adjustFn(
462 index, replaceFn, list
463){
464 const actualIndex = index < 0 ? list.length + index : index
465 if (index >= list.length || actualIndex < 0) return list
466
467 const clone = list.slice()
468 clone[ actualIndex ] = replaceFn(clone[ actualIndex ])
469
470 return clone
471}
472
473export const adjust = curry(adjustFn)
474```
475
476</details>
477
478<details>
479
480<summary><strong>Tests</strong></summary>
481
482```javascript
483import { add } from './add'
484import { adjust } from './adjust'
485import { pipe } from './pipe'
486
487const list = [ 0, 1, 2 ]
488const expected = [ 0, 11, 2 ]
489
490test('happy', () => {})
491
492test('happy', () => {
493 expect(adjust(
494 1, add(10), list
495 )).toEqual(expected)
496})
497
498test('with curring type 1 1 1', () => {
499 expect(adjust(1)(add(10))(list)).toEqual(expected)
500})
501
502test('with curring type 1 2', () => {
503 expect(adjust(1)(add(10), list)).toEqual(expected)
504})
505
506test('with curring type 2 1', () => {
507 expect(adjust(1, add(10))(list)).toEqual(expected)
508})
509
510test('with negative index', () => {
511 expect(adjust(
512 -2, add(10), list
513 )).toEqual(expected)
514})
515
516test('when index is out of bounds', () => {
517 const list = [ 0, 1, 2, 3 ]
518 expect(adjust(
519 4, add(1), list
520 )).toEqual(list)
521 expect(adjust(
522 -5, add(1), list
523 )).toEqual(list)
524})
525```
526
527</details>
528
529<details>
530
531<summary>1 failed <italic>Ramda.adjust</italic> specs
532
533> :boom: Reason for the failure: Ramda method accepts an array-like object
534</summary>
535
536```javascript
537var R = require('../../../../dist/rambda.js');
538var eq = require('./shared/eq');
539
540describe('adjust', function() {
541 it('accepts an array-like object', function() {
542 function args() {
543 return arguments;
544 }
545 eq(R.adjust(2, R.add(1), args(0, 1, 2, 3)), [0, 1, 3, 3]);
546 });
547});
548```
549
550</details>
551
552[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#adjust)
553
554### all
555
556```typescript
557
558all<T>(predicate: (x: T) => boolean, list: T[]): boolean
559```
560
561It returns `true`, if all members of array `list` returns `true`, when applied as argument to `predicate` function.
562
563```javascript
564const list = [ 0, 1, 2, 3, 4 ]
565const predicate = x => x > -1
566
567const result = R.all(predicate, list)
568// => true
569```
570
571<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%200%2C%201%2C%202%2C%203%2C%204%20%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%20-1%0A%0Aconst%20result%20%3D%20R.all(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.all</strong> example in Rambda REPL</a>
572
573<details>
574
575<summary>All Typescript definitions</summary>
576
577```typescript
578all<T>(predicate: (x: T) => boolean, list: T[]): boolean;
579all<T>(predicate: (x: T) => boolean): (list: T[]) => boolean;
580```
581
582</details>
583
584<details>
585
586<summary><strong>R.all</strong> source</summary>
587
588```javascript
589export function all(predicate, list){
590 if (arguments.length === 1) return _list => all(predicate, _list)
591
592 for (let i = 0; i < list.length; i++){
593 if (!predicate(list[ i ])) return false
594 }
595
596 return true
597}
598```
599
600</details>
601
602<details>
603
604<summary><strong>Tests</strong></summary>
605
606```javascript
607import { all } from './all'
608
609const list = [ 0, 1, 2, 3, 4 ]
610
611test('when true', () => {
612 const fn = x => x > -1
613
614 expect(all(fn)(list)).toBeTrue()
615})
616
617test('when false', () => {
618 const fn = x => x > 2
619
620 expect(all(fn, list)).toBeFalse()
621})
622```
623
624</details>
625
626<details>
627
628<summary><strong>Typescript</strong> test</summary>
629
630```typescript
631import {all} from 'rambda'
632
633describe('all', () => {
634 it('happy', () => {
635 const result = all(
636 x => {
637 x // $ExpectType number
638 return x > 0
639 },
640 [1, 2, 3]
641 )
642 result // $ExpectType boolean
643 })
644 it('curried needs a type', () => {
645 const result = all<number>(x => {
646 x // $ExpectType number
647 return x > 0
648 })([1, 2, 3])
649 result // $ExpectType boolean
650 })
651})
652```
653
654</details>
655
656[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#all)
657
658### allPass
659
660```typescript
661
662allPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean
663```
664
665It returns `true`, if all functions of `predicates` return `true`, when `input` is their argument.
666
667```javascript
668const input = {
669 a : 1,
670 b : 2,
671}
672const predicates = [
673 x => x.a === 1,
674 x => x.b === 2,
675]
676const result = R.allPass(predicates)(input) // => true
677```
678
679<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20input%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%202%2C%0A%7D%0Aconst%20predicates%20%3D%20%5B%0A%20%20x%20%3D%3E%20x.a%20%3D%3D%3D%201%2C%0A%20%20x%20%3D%3E%20x.b%20%3D%3D%3D%202%2C%0A%5D%0Aconst%20result%20%3D%20R.allPass(predicates)(input)%20%2F%2F%20%3D%3E%20true">Try this <strong>R.allPass</strong> example in Rambda REPL</a>
680
681<details>
682
683<summary>All Typescript definitions</summary>
684
685```typescript
686allPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean;
687```
688
689</details>
690
691<details>
692
693<summary><strong>R.allPass</strong> source</summary>
694
695```javascript
696export function allPass(predicates){
697 return input => {
698 let counter = 0
699 while (counter < predicates.length){
700 if (!predicates[ counter ](input)){
701 return false
702 }
703 counter++
704 }
705
706 return true
707 }
708}
709```
710
711</details>
712
713<details>
714
715<summary><strong>Tests</strong></summary>
716
717```javascript
718import { allPass } from './allPass'
719
720test('happy', () => {
721 const rules = [ x => typeof x === 'number', x => x > 10, x => x * 7 < 100 ]
722
723 expect(allPass(rules)(11)).toBeTrue()
724
725 expect(allPass(rules)(undefined)).toBeFalse()
726})
727
728test('when returns true', () => {
729 const conditionArr = [ val => val.a === 1, val => val.b === 2 ]
730
731 expect(allPass(conditionArr)({
732 a : 1,
733 b : 2,
734 })).toBeTrue()
735})
736
737test('when returns false', () => {
738 const conditionArr = [ val => val.a === 1, val => val.b === 3 ]
739
740 expect(allPass(conditionArr)({
741 a : 1,
742 b : 2,
743 })).toBeFalse()
744})
745```
746
747</details>
748
749<details>
750
751<summary><strong>Typescript</strong> test</summary>
752
753```typescript
754import {allPass} from 'rambda'
755
756describe('allPass', () => {
757 it('happy', () => {
758 const x = allPass<number>([
759 y => {
760 y // $ExpectType number
761 return typeof y === 'number'
762 },
763 y => {
764 return y > 0
765 },
766 ])(11)
767
768 x // $ExpectType boolean
769 })
770})
771```
772
773</details>
774
775<details>
776
777<summary>1 failed <italic>Ramda.allPass</italic> specs
778
779> :boom: Reason for the failure: Ramda method returns a curried function whose arity matches that of the highest-arity predicate
780</summary>
781
782```javascript
783var R = require('../../../../dist/rambda.js');
784var eq = require('./shared/eq');
785
786describe('allPass', function() {
787 var odd = function(n) { return n % 2 !== 0; };
788 var lt20 = function(n) { return n < 20; };
789 var gt5 = function(n) { return n > 5; };
790 var plusEq = function(w, x, y, z) { return w + x === y + z; };
791 it('returns a curried function whose arity matches that of the highest-arity predicate', function() {
792 eq(R.allPass([odd, gt5, plusEq]).length, 4);
793 eq(R.allPass([odd, gt5, plusEq])(9, 9, 9, 9), true);
794 eq(R.allPass([odd, gt5, plusEq])(9)(9)(9)(9), true);
795 });
796});
797```
798
799</details>
800
801[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#allPass)
802
803### always
804
805```typescript
806
807always<T>(x: T): () => T
808```
809
810It returns function that always returns `x`.
811
812```javascript
813const fn = R.always(7)
814
815console.log(fn())// => 7
816```
817
818<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20R.always(7)%0A%0Aconsole.log(fn())%2F%2F%20%3D%3E%207">Try this <strong>R.always</strong> example in Rambda REPL</a>
819
820<details>
821
822<summary>All Typescript definitions</summary>
823
824```typescript
825always<T>(x: T): () => T;
826```
827
828</details>
829
830<details>
831
832<summary><strong>R.always</strong> source</summary>
833
834```javascript
835export function always(x){
836 return () => x
837}
838```
839
840</details>
841
842<details>
843
844<summary><strong>Tests</strong></summary>
845
846```javascript
847import { always } from './always'
848import { F } from './F'
849
850test('happy', () => {
851 const fn = always(7)
852
853 expect(fn()).toEqual(7)
854 expect(fn()).toEqual(7)
855})
856
857test('f', () => {
858 const fn = always(F())
859
860 expect(fn()).toBeFalse()
861 expect(fn()).toBeFalse()
862})
863```
864
865</details>
866
867<details>
868
869<summary><strong>Typescript</strong> test</summary>
870
871```typescript
872import {always} from 'rambda'
873
874describe('R.always', () => {
875 it('happy', () => {
876 const fn = always('foo')
877 fn // $ExpectType () => string
878 const result = fn()
879 result // $ExpectType string
880 })
881})
882```
883
884</details>
885
886[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#always)
887
888### and
889
890```typescript
891
892and<T, U>(x: T, y: U): T | U
893```
894
895Logical AND
896
897```javascript
898R.and(true, true); // => true
899R.and(false, true); // => false
900R.and(true, 'foo'); // => 'foo'
901```
902
903<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.and(true%2C%20true)%3B%20%2F%2F%20%3D%3E%20true%0AR.and(false%2C%20true)%3B%20%2F%2F%20%3D%3E%20false%0AR.and(true%2C%20'foo')%3B%20%2F%2F%20%3D%3E%20'foo'">Try this <strong>R.and</strong> example in Rambda REPL</a>
904
905<details>
906
907<summary>All Typescript definitions</summary>
908
909```typescript
910and<T, U>(x: T, y: U): T | U;
911and<T>(x: T): <U>(y: U) => T | U;
912```
913
914</details>
915
916<details>
917
918<summary><strong>R.and</strong> source</summary>
919
920```javascript
921export function and(a, b){
922 if (arguments.length === 1) return _b => and(a, _b)
923
924 return a && b
925}
926```
927
928</details>
929
930<details>
931
932<summary><strong>Tests</strong></summary>
933
934```javascript
935import { and } from './and'
936
937test('happy', () => {
938 expect(and(1, 'foo')).toBe('foo')
939 expect(and(true, true)).toBeTrue()
940 expect(and(true)(true)).toBeTrue()
941 expect(and(true, false)).toBeFalse()
942 expect(and(false, true)).toBeFalse()
943 expect(and(false, false)).toBeFalse()
944})
945```
946
947</details>
948
949<details>
950
951<summary><strong>Typescript</strong> test</summary>
952
953```typescript
954import {and} from 'rambda'
955
956describe('R.and', () => {
957 it('happy', () => {
958 const result = and(true, false)
959 result // $ExpectType boolean
960 })
961 it('curried', () => {
962 const result = and('foo')(1)
963 result // $ExpectType string | 1
964 })
965})
966```
967
968</details>
969
970[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#and)
971
972### any
973
974```typescript
975
976any<T>(predicate: (x: T) => boolean, list: readonly T[]): boolean
977```
978
979It returns `true`, if at least one member of `list` returns true, when passed to a `predicate` function.
980
981```javascript
982const list = [1, 2, 3]
983const predicate = x => x * x > 8
984R.any(fn, list)
985// => true
986```
987
988<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20*%20x%20%3E%208%0AR.any(fn%2C%20list)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.any</strong> example in Rambda REPL</a>
989
990<details>
991
992<summary>All Typescript definitions</summary>
993
994```typescript
995any<T>(predicate: (x: T) => boolean, list: readonly T[]): boolean;
996any<T>(predicate: (x: T) => boolean): (list: readonly T[]) => boolean;
997```
998
999</details>
1000
1001<details>
1002
1003<summary><strong>R.any</strong> source</summary>
1004
1005```javascript
1006export function any(predicate, list){
1007 if (arguments.length === 1) return _list => any(predicate, _list)
1008
1009 let counter = 0
1010 while (counter < list.length){
1011 if (predicate(list[ counter ], counter)){
1012 return true
1013 }
1014 counter++
1015 }
1016
1017 return false
1018}
1019```
1020
1021</details>
1022
1023<details>
1024
1025<summary><strong>Tests</strong></summary>
1026
1027```javascript
1028import { any } from './any'
1029
1030const list = [ 1, 2, 3 ]
1031
1032test('happy', () => {
1033 expect(any(x => x < 0, list)).toBeFalse()
1034})
1035
1036test('with curry', () => {
1037 expect(any(x => x > 2)(list)).toBeTrue()
1038})
1039```
1040
1041</details>
1042
1043<details>
1044
1045<summary><strong>Typescript</strong> test</summary>
1046
1047```typescript
1048import {any} from 'rambda'
1049
1050describe('R.any', () => {
1051 it('happy', () => {
1052 const result = any(
1053 x => {
1054 x // $ExpectType number
1055 return x > 2
1056 },
1057 [1, 2, 3]
1058 )
1059 result // $ExpectType boolean
1060 })
1061
1062 it('when curried needs a type', () => {
1063 const result = any<number>(x => {
1064 x // $ExpectType number
1065 return x > 2
1066 })([1, 2, 3])
1067 result // $ExpectType boolean
1068 })
1069})
1070```
1071
1072</details>
1073
1074[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#any)
1075
1076### anyPass
1077
1078```typescript
1079
1080anyPass<T>(predicates: SafePred<T>[]): SafePred<T>
1081```
1082
1083It accepts list of `predicates` and returns a function. This function with its `input` will return `true`, if any of `predicates` returns `true` for this `input`.
1084
1085```javascript
1086const isBig = x => x > 20
1087const isOdd = x => x % 2 === 1
1088const input = 11
1089
1090const fn = R.anyPass(
1091 [isBig, isOdd]
1092)
1093
1094const result = fn(input)
1095// => true
1096```
1097
1098<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20isBig%20%3D%20x%20%3D%3E%20x%20%3E%2020%0Aconst%20isOdd%20%3D%20x%20%3D%3E%20x%20%25%202%20%3D%3D%3D%201%0Aconst%20input%20%3D%2011%0A%0Aconst%20fn%20%3D%20R.anyPass(%0A%20%20%5BisBig%2C%20isOdd%5D%0A)%0A%0Aconst%20result%20%3D%20fn(input)%20%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.anyPass</strong> example in Rambda REPL</a>
1099
1100<details>
1101
1102<summary>All Typescript definitions</summary>
1103
1104```typescript
1105anyPass<T>(predicates: SafePred<T>[]): SafePred<T>;
1106```
1107
1108</details>
1109
1110<details>
1111
1112<summary><strong>R.anyPass</strong> source</summary>
1113
1114```javascript
1115export function anyPass(predicates){
1116 return input => {
1117 let counter = 0
1118 while (counter < predicates.length){
1119 if (predicates[ counter ](input)){
1120 return true
1121 }
1122 counter++
1123 }
1124
1125 return false
1126 }
1127}
1128```
1129
1130</details>
1131
1132<details>
1133
1134<summary><strong>Tests</strong></summary>
1135
1136```javascript
1137import { anyPass } from './anyPass'
1138
1139test('happy', () => {
1140 const rules = [ x => typeof x === 'string', x => x > 10 ]
1141 const predicate = anyPass(rules)
1142 expect(predicate('foo')).toBeTrue()
1143 expect(predicate(6)).toBeFalse()
1144})
1145
1146test('happy', () => {
1147 const rules = [ x => typeof x === 'string', x => x > 10 ]
1148
1149 expect(anyPass(rules)(11)).toBeTrue()
1150
1151 expect(anyPass(rules)(undefined)).toBeFalse()
1152})
1153
1154const obj = {
1155 a : 1,
1156 b : 2,
1157}
1158
1159test('when returns true', () => {
1160 const conditionArr = [ val => val.a === 1, val => val.a === 2 ]
1161
1162 expect(anyPass(conditionArr)(obj)).toBeTrue()
1163})
1164
1165test('when returns false + curry', () => {
1166 const conditionArr = [ val => val.a === 2, val => val.b === 3 ]
1167
1168 expect(anyPass(conditionArr)(obj)).toBeFalse()
1169})
1170
1171test('happy', () => {
1172 expect(anyPass([])(3)).toEqual(false)
1173})
1174```
1175
1176</details>
1177
1178<details>
1179
1180<summary><strong>Typescript</strong> test</summary>
1181
1182```typescript
1183import {anyPass} from 'rambda'
1184
1185describe('anyPass', () => {
1186 it('happy', () => {
1187 const x = anyPass<number>([
1188 y => {
1189 y // $ExpectType number
1190 return typeof y === 'number'
1191 },
1192 y => {
1193 return y > 0
1194 },
1195 ])(11)
1196
1197 x // $ExpectType boolean
1198 })
1199})
1200```
1201
1202</details>
1203
1204<details>
1205
1206<summary>1 failed <italic>Ramda.anyPass</italic> specs
1207
1208> :boom: Reason for the failure: Ramda method returns a curried function whose arity matches that of the highest-arity predicate
1209</summary>
1210
1211```javascript
1212var R = require('../../../../dist/rambda.js');
1213var eq = require('./shared/eq');
1214
1215describe('anyPass', function() {
1216 var odd = function(n) { return n % 2 !== 0; };
1217 var gt20 = function(n) { return n > 20; };
1218 var lt5 = function(n) { return n < 5; };
1219 var plusEq = function(w, x, y, z) { return w + x === y + z; };
1220 it('returns a curried function whose arity matches that of the highest-arity predicate', function() {
1221 eq(R.anyPass([odd, lt5, plusEq]).length, 4);
1222 eq(R.anyPass([odd, lt5, plusEq])(6, 7, 8, 9), false);
1223 eq(R.anyPass([odd, lt5, plusEq])(6)(7)(8)(9), false);
1224 });
1225});
1226```
1227
1228</details>
1229
1230[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#anyPass)
1231
1232### append
1233
1234```typescript
1235
1236append<T>(x: T, list: readonly T[]): T[]
1237```
1238
1239It adds element `x` at the end of `list`.
1240
1241```javascript
1242const x = 'foo'
1243
1244const result = R.append(x, ['bar', 'baz'])
1245// => ['bar', 'baz', 'foo']
1246```
1247
1248<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20x%20%3D%20'foo'%0A%0Aconst%20result%20%3D%20R.append(x%2C%20%5B'bar'%2C%20'baz'%5D)%0A%2F%2F%20%3D%3E%20%5B'bar'%2C%20'baz'%2C%20'foo'%5D">Try this <strong>R.append</strong> example in Rambda REPL</a>
1249
1250<details>
1251
1252<summary>All Typescript definitions</summary>
1253
1254```typescript
1255append<T>(x: T, list: readonly T[]): T[];
1256append<T>(x: T): <T>(list: readonly T[]) => T[];
1257```
1258
1259</details>
1260
1261<details>
1262
1263<summary><strong>R.append</strong> source</summary>
1264
1265```javascript
1266export function append(x, input){
1267 if (arguments.length === 1) return _input => append(x, _input)
1268
1269 if (typeof input === 'string') return input.split('').concat(x)
1270
1271 const clone = input.slice()
1272 clone.push(x)
1273
1274 return clone
1275}
1276```
1277
1278</details>
1279
1280<details>
1281
1282<summary><strong>Tests</strong></summary>
1283
1284```javascript
1285import { append } from './append'
1286
1287test('happy', () => {
1288 expect(append('tests', [ 'write', 'more' ])).toEqual([
1289 'write',
1290 'more',
1291 'tests',
1292 ])
1293})
1294
1295test('append to empty array', () => {
1296 expect(append('tests')([])).toEqual([ 'tests' ])
1297})
1298
1299test('with strings', () => {
1300 expect(append('o', 'fo')).toEqual([ 'f', 'o', 'o' ])
1301})
1302```
1303
1304</details>
1305
1306<details>
1307
1308<summary><strong>Typescript</strong> test</summary>
1309
1310```typescript
1311import {append} from 'rambda'
1312
1313const list = [1, 2, 3]
1314
1315describe('R.append', () => {
1316 it('happy', () => {
1317 const result = append(4, list)
1318
1319 result // $ExpectType number[]
1320 })
1321 it('curried', () => {
1322 const result = append(4)(list)
1323
1324 result // $ExpectType number[]
1325 })
1326})
1327```
1328
1329</details>
1330
1331[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#append)
1332
1333### applySpec
1334
1335```typescript
1336
1337applySpec<Spec extends Record<string, (...args: readonly any[]) => any>>(
1338 spec: Spec
1339): (
1340 ...args: Parameters<ValueOfRecord<Spec>>
1341) => { [Key in keyof Spec]: ReturnType<Spec[Key]> }
1342```
1343
1344> :boom: The currying in this function works best with functions with 4 arguments or less. (arity of 4)
1345
1346```javascript
1347const fn = R.applySpec({
1348 sum: R.add,
1349 nested: { mul: R.multiply }
1350})
1351const result = fn(2, 4)
1352// => { sum: 6, nested: { mul: 8 } }
1353```
1354
1355<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20R.applySpec(%7B%0A%20%20sum%3A%20R.add%2C%0A%20%20nested%3A%20%7B%20mul%3A%20R.multiply%20%7D%0A%7D)%0Aconst%20result%20%3D%20fn(2%2C%204)%20%0A%2F%2F%20%3D%3E%20%7B%20sum%3A%206%2C%20nested%3A%20%7B%20mul%3A%208%20%7D%20%7D">Try this <strong>R.applySpec</strong> example in Rambda REPL</a>
1356
1357<details>
1358
1359<summary>All Typescript definitions</summary>
1360
1361```typescript
1362applySpec<Spec extends Record<string, (...args: readonly any[]) => any>>(
1363 spec: Spec
1364): (
1365 ...args: Parameters<ValueOfRecord<Spec>>
1366) => { [Key in keyof Spec]: ReturnType<Spec[Key]> };
1367applySpec<T>(spec: any): (...args: readonly any[]) => T;
1368```
1369
1370</details>
1371
1372<details>
1373
1374<summary><strong>R.applySpec</strong> source</summary>
1375
1376```javascript
1377import { _isArray } from './_internals/_isArray'
1378
1379// recursively traverse the given spec object to find the highest arity function
1380function __findHighestArity(spec, max = 0){
1381 for (const key in spec){
1382 if (spec.hasOwnProperty(key) === false || key === 'constructor') continue
1383
1384 if (typeof spec[ key ] === 'object'){
1385 max = Math.max(max, __findHighestArity(spec[ key ]))
1386 }
1387
1388 if (typeof spec[ key ] === 'function'){
1389 max = Math.max(max, spec[ key ].length)
1390 }
1391 }
1392
1393 return max
1394}
1395
1396function __filterUndefined(){
1397 const defined = []
1398 let i = 0
1399 const l = arguments.length
1400 while (i < l){
1401 if (typeof arguments[ i ] === 'undefined') break
1402 defined[ i ] = arguments[ i ]
1403 i++
1404 }
1405
1406 return defined
1407}
1408
1409function __applySpecWithArity(
1410 spec, arity, cache
1411){
1412 const remaining = arity - cache.length
1413
1414 if (remaining === 1)
1415 return x =>
1416 __applySpecWithArity(
1417 spec, arity, __filterUndefined(...cache, x)
1418 )
1419 if (remaining === 2)
1420 return (x, y) =>
1421 __applySpecWithArity(
1422 spec, arity, __filterUndefined(
1423 ...cache, x, y
1424 )
1425 )
1426 if (remaining === 3)
1427 return (
1428 x, y, z
1429 ) =>
1430 __applySpecWithArity(
1431 spec, arity, __filterUndefined(
1432 ...cache, x, y, z
1433 )
1434 )
1435 if (remaining === 4)
1436 return (
1437 x, y, z, a
1438 ) =>
1439 __applySpecWithArity(
1440 spec,
1441 arity,
1442 __filterUndefined(
1443 ...cache, x, y, z, a
1444 )
1445 )
1446 if (remaining > 4)
1447 return (...args) =>
1448 __applySpecWithArity(
1449 spec, arity, __filterUndefined(...cache, ...args)
1450 )
1451
1452 // handle spec as Array
1453 if (_isArray(spec)){
1454 const ret = []
1455 let i = 0
1456 const l = spec.length
1457 for (; i < l; i++){
1458 // handle recursive spec inside array
1459 if (typeof spec[ i ] === 'object' || _isArray(spec[ i ])){
1460 ret[ i ] = __applySpecWithArity(
1461 spec[ i ], arity, cache
1462 )
1463 }
1464 // apply spec to the key
1465 if (typeof spec[ i ] === 'function'){
1466 ret[ i ] = spec[ i ](...cache)
1467 }
1468 }
1469
1470 return ret
1471 }
1472
1473 // handle spec as Object
1474 const ret = {}
1475 // apply callbacks to each property in the spec object
1476 for (const key in spec){
1477 if (spec.hasOwnProperty(key) === false || key === 'constructor') continue
1478
1479 // apply the spec recursively
1480 if (typeof spec[ key ] === 'object'){
1481 ret[ key ] = __applySpecWithArity(
1482 spec[ key ], arity, cache
1483 )
1484 continue
1485 }
1486
1487 // apply spec to the key
1488 if (typeof spec[ key ] === 'function'){
1489 ret[ key ] = spec[ key ](...cache)
1490 }
1491 }
1492
1493 return ret
1494}
1495
1496export function applySpec(spec, ...args){
1497 // get the highest arity spec function, cache the result and pass to __applySpecWithArity
1498 const arity = __findHighestArity(spec)
1499
1500 if (arity === 0){
1501 return () => ({})
1502 }
1503 const toReturn = __applySpecWithArity(
1504 spec, arity, args
1505 )
1506
1507 return toReturn
1508}
1509```
1510
1511</details>
1512
1513<details>
1514
1515<summary><strong>Tests</strong></summary>
1516
1517```javascript
1518import { applySpec as applySpecRamda, nAry } from 'ramda'
1519
1520import { add, always, compose, dec, inc, map, path, prop, T } from '../rambda'
1521import { applySpec } from './applySpec'
1522
1523test('different than Ramda when bad spec', () => {
1524 const result = applySpec({ sum : { a : 1 } })(1, 2)
1525 const ramdaResult = applySpecRamda({ sum : { a : 1 } })(1, 2)
1526 expect(result).toEqual({})
1527 expect(ramdaResult).toEqual({ sum : { a : {} } })
1528})
1529
1530test('works with empty spec', () => {
1531 expect(applySpec({})()).toEqual({})
1532 expect(applySpec([])(1, 2)).toEqual({})
1533 expect(applySpec(null)(1, 2)).toEqual({})
1534})
1535
1536test('works with unary functions', () => {
1537 const result = applySpec({
1538 v : inc,
1539 u : dec,
1540 })(1)
1541 const expected = {
1542 v : 2,
1543 u : 0,
1544 }
1545 expect(result).toEqual(expected)
1546})
1547
1548test('works with binary functions', () => {
1549 const result = applySpec({ sum : add })(1, 2)
1550 expect(result).toEqual({ sum : 3 })
1551})
1552
1553test('works with nested specs', () => {
1554 const result = applySpec({
1555 unnested : always(0),
1556 nested : { sum : add },
1557 })(1, 2)
1558 const expected = {
1559 unnested : 0,
1560 nested : { sum : 3 },
1561 }
1562 expect(result).toEqual(expected)
1563})
1564
1565test('works with arrays of nested specs', () => {
1566 const result = applySpec({
1567 unnested : always(0),
1568 nested : [ { sum : add } ],
1569 })(1, 2)
1570
1571 expect(result).toEqual({
1572 unnested : 0,
1573 nested : [ { sum : 3 } ],
1574 })
1575})
1576
1577test('works with arrays of spec objects', () => {
1578 const result = applySpec([ { sum : add } ])(1, 2)
1579
1580 expect(result).toEqual([ { sum : 3 } ])
1581})
1582
1583test('works with arrays of functions', () => {
1584 const result = applySpec([ map(prop('a')), map(prop('b')) ])([
1585 {
1586 a : 'a1',
1587 b : 'b1',
1588 },
1589 {
1590 a : 'a2',
1591 b : 'b2',
1592 },
1593 ])
1594 const expected = [
1595 [ 'a1', 'a2' ],
1596 [ 'b1', 'b2' ],
1597 ]
1598 expect(result).toEqual(expected)
1599})
1600
1601test('works with a spec defining a map key', () => {
1602 expect(applySpec({ map : prop('a') })({ a : 1 })).toEqual({ map : 1 })
1603})
1604
1605test('cannot retains the highest arity', () => {
1606 const f = applySpec({
1607 f1 : nAry(2, T),
1608 f2 : nAry(5, T),
1609 })
1610 const fRamda = applySpecRamda({
1611 f1 : nAry(2, T),
1612 f2 : nAry(5, T),
1613 })
1614 expect(f.length).toBe(0)
1615 expect(fRamda.length).toBe(5)
1616})
1617
1618test('returns a curried function', () => {
1619 expect(applySpec({ sum : add })(1)(2)).toEqual({ sum : 3 })
1620})
1621
1622// Additional tests
1623// ============================================
1624test('arity', () => {
1625 const spec = {
1626 one : x1 => x1,
1627 two : (x1, x2) => x1 + x2,
1628 three : (
1629 x1, x2, x3
1630 ) => x1 + x2 + x3,
1631 }
1632 expect(applySpec(
1633 spec, 1, 2, 3
1634 )).toEqual({
1635 one : 1,
1636 two : 3,
1637 three : 6,
1638 })
1639})
1640
1641test('arity over 5 arguments', () => {
1642 const spec = {
1643 one : x1 => x1,
1644 two : (x1, x2) => x1 + x2,
1645 three : (
1646 x1, x2, x3
1647 ) => x1 + x2 + x3,
1648 four : (
1649 x1, x2, x3, x4
1650 ) => x1 + x2 + x3 + x4,
1651 five : (
1652 x1, x2, x3, x4, x5
1653 ) => x1 + x2 + x3 + x4 + x5,
1654 }
1655 expect(applySpec(
1656 spec, 1, 2, 3, 4, 5
1657 )).toEqual({
1658 one : 1,
1659 two : 3,
1660 three : 6,
1661 four : 10,
1662 five : 15,
1663 })
1664})
1665
1666test('curried', () => {
1667 const spec = {
1668 one : x1 => x1,
1669 two : (x1, x2) => x1 + x2,
1670 three : (
1671 x1, x2, x3
1672 ) => x1 + x2 + x3,
1673 }
1674 expect(applySpec(spec)(1)(2)(3)).toEqual({
1675 one : 1,
1676 two : 3,
1677 three : 6,
1678 })
1679})
1680
1681test('curried over 5 arguments', () => {
1682 const spec = {
1683 one : x1 => x1,
1684 two : (x1, x2) => x1 + x2,
1685 three : (
1686 x1, x2, x3
1687 ) => x1 + x2 + x3,
1688 four : (
1689 x1, x2, x3, x4
1690 ) => x1 + x2 + x3 + x4,
1691 five : (
1692 x1, x2, x3, x4, x5
1693 ) => x1 + x2 + x3 + x4 + x5,
1694 }
1695 expect(applySpec(spec)(1)(2)(3)(4)(5)).toEqual({
1696 one : 1,
1697 two : 3,
1698 three : 6,
1699 four : 10,
1700 five : 15,
1701 })
1702})
1703
1704test('undefined property', () => {
1705 const spec = { prop : path([ 'property', 'doesnt', 'exist' ]) }
1706 expect(applySpec(spec, {})).toEqual({ prop : undefined })
1707})
1708
1709test('restructure json object', () => {
1710 const spec = {
1711 id : path('user.id'),
1712 name : path('user.firstname'),
1713 profile : path('user.profile'),
1714 doesntExist : path('user.profile.doesntExist'),
1715 info : { views : compose(inc, prop('views')) },
1716 type : always('playa'),
1717 }
1718
1719 const data = {
1720 user : {
1721 id : 1337,
1722 firstname : 'john',
1723 lastname : 'shaft',
1724 profile : 'shaft69',
1725 },
1726 views : 42,
1727 }
1728
1729 expect(applySpec(spec, data)).toEqual({
1730 id : 1337,
1731 name : 'john',
1732 profile : 'shaft69',
1733 doesntExist : undefined,
1734 info : { views : 43 },
1735 type : 'playa',
1736 })
1737})
1738```
1739
1740</details>
1741
1742<details>
1743
1744<summary><strong>Typescript</strong> test</summary>
1745
1746```typescript
1747import {multiply, applySpec, inc, dec, add} from 'rambda'
1748
1749describe('applySpec', () => {
1750 it('ramda 1', () => {
1751 const result = applySpec({
1752 v: inc,
1753 u: dec,
1754 })(1)
1755 result // $ExpectType { v: number; u: number; }
1756 })
1757 it('ramda 1', () => {
1758 interface Output {
1759 sum: number,
1760 multiplied: number,
1761 }
1762 const result = applySpec<Output>({
1763 sum: add,
1764 multiplied: multiply,
1765 })(1, 2)
1766
1767 result // $ExpectType Output
1768 })
1769})
1770```
1771
1772</details>
1773
1774[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#applySpec)
1775
1776### assoc
1777
1778```typescript
1779
1780assoc<T, U, K extends string>(prop: K, val: T, obj: U): Record<K, T> & U
1781```
1782
1783It makes a shallow clone of `obj` with setting or overriding the property `prop` with `newValue`.
1784
1785> :boom: This copies and flattens prototype properties
1786onto the new object as well. All non-primitive properties are copied by
1787reference.
1788
1789```javascript
1790R.assoc('c', 3, {a: 1, b: 2})
1791//=> {a: 1, b: 2, c: 3}
1792```
1793
1794<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.assoc('c'%2C%203%2C%20%7Ba%3A%201%2C%20b%3A%202%7D)%0A%2F%2F%3D%3E%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D">Try this <strong>R.assoc</strong> example in Rambda REPL</a>
1795
1796<details>
1797
1798<summary>All Typescript definitions</summary>
1799
1800```typescript
1801assoc<T, U, K extends string>(prop: K, val: T, obj: U): Record<K, T> & U;
1802assoc<T, K extends string>(prop: K, val: T): <U>(obj: U) => Record<K, T> & U;
1803assoc<K extends string>(prop: K): AssocPartialOne<K>;
1804```
1805
1806</details>
1807
1808<details>
1809
1810<summary><strong>R.assoc</strong> source</summary>
1811
1812```javascript
1813import { curry } from './curry'
1814
1815function assocFn(
1816 prop, newValue, obj
1817){
1818 return Object.assign(
1819 {}, obj, { [ prop ] : newValue }
1820 )
1821}
1822
1823export const assoc = curry(assocFn)
1824```
1825
1826</details>
1827
1828<details>
1829
1830<summary><strong>Tests</strong></summary>
1831
1832```javascript
1833import { assoc } from './assoc'
1834
1835test('adds a key to an empty object', () => {
1836 expect(assoc(
1837 'a', 1, {}
1838 )).toEqual({ a : 1 })
1839})
1840
1841test('adds a key to a non-empty object', () => {
1842 expect(assoc(
1843 'b', 2, { a : 1 }
1844 )).toEqual({
1845 a : 1,
1846 b : 2,
1847 })
1848})
1849
1850test('adds a key to a non-empty object - curry case 1', () => {
1851 expect(assoc('b', 2)({ a : 1 })).toEqual({
1852 a : 1,
1853 b : 2,
1854 })
1855})
1856
1857test('adds a key to a non-empty object - curry case 2', () => {
1858 expect(assoc('b')(2, { a : 1 })).toEqual({
1859 a : 1,
1860 b : 2,
1861 })
1862})
1863
1864test('adds a key to a non-empty object - curry case 3', () => {
1865 const result = assoc('b')(2)({ a : 1 })
1866
1867 expect(result).toEqual({
1868 a : 1,
1869 b : 2,
1870 })
1871})
1872
1873test('changes an existing key', () => {
1874 expect(assoc(
1875 'a', 2, { a : 1 }
1876 )).toEqual({ a : 2 })
1877})
1878
1879test('undefined is considered an empty object', () => {
1880 expect(assoc(
1881 'a', 1, undefined
1882 )).toEqual({ a : 1 })
1883})
1884
1885test('null is considered an empty object', () => {
1886 expect(assoc(
1887 'a', 1, null
1888 )).toEqual({ a : 1 })
1889})
1890
1891test('value can be null', () => {
1892 expect(assoc(
1893 'a', null, null
1894 )).toEqual({ a : null })
1895})
1896
1897test('value can be undefined', () => {
1898 expect(assoc(
1899 'a', undefined, null
1900 )).toEqual({ a : undefined })
1901})
1902
1903test('assignment is shallow', () => {
1904 expect(assoc(
1905 'a', { b : 2 }, { a : { c : 3 } }
1906 )).toEqual({ a : { b : 2 } })
1907})
1908```
1909
1910</details>
1911
1912<details>
1913
1914<summary><strong>Typescript</strong> test</summary>
1915
1916```typescript
1917import {assoc} from 'rambda'
1918
1919const obj = {a: 1}
1920const newValue = 2
1921const newProp = 'b'
1922
1923describe('R.assoc', () => {
1924 it('happy', () => {
1925 const result = assoc(newProp, newValue, obj)
1926
1927 result.a // $ExpectType number
1928 result.b // $ExpectType number
1929 })
1930 it('curried 1', () => {
1931 const result = assoc(newProp, newValue)(obj)
1932
1933 result.a // $ExpectType number
1934 result.b // $ExpectType number
1935 })
1936 it('curried 2', () => {
1937 const result = assoc(newProp)(newValue)(obj)
1938
1939 result.a // $ExpectType number
1940 result.b // $ExpectType number
1941 })
1942})
1943```
1944
1945</details>
1946
1947[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#assoc)
1948
1949### assocPath
1950
1951```typescript
1952
1953assocPath<Output>(path: Path, newValue: any, obj: object): Output
1954```
1955
1956It makes a shallow clone of `obj` with setting or overriding with `newValue` the property found with `path`.
1957
1958```javascript
1959const path = 'b.c'
1960const newValue = 2
1961const obj = { a: 1 }
1962
1963R.assocPath(path, newValue, obj)
1964// => { a : 1, b : { c : 2 }}
1965```
1966
1967<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20path%20%3D%20'b.c'%0Aconst%20newValue%20%3D%202%0Aconst%20obj%20%3D%20%7B%20a%3A%201%20%7D%0A%0AR.assocPath(path%2C%20newValue%2C%20obj)%0A%2F%2F%20%3D%3E%20%7B%20a%20%3A%201%2C%20b%20%3A%20%7B%20c%20%3A%202%20%7D%7D">Try this <strong>R.assocPath</strong> example in Rambda REPL</a>
1968
1969<details>
1970
1971<summary>All Typescript definitions</summary>
1972
1973```typescript
1974assocPath<Output>(path: Path, newValue: any, obj: object): Output;
1975assocPath<Output>(path: Path, newValue: any): (obj: object) => Output;
1976assocPath<Output>(path: Path): FunctionToolbelt.Curry<(newValue: any, obj: object) => Output>;
1977```
1978
1979</details>
1980
1981<details>
1982
1983<summary><strong>R.assocPath</strong> source</summary>
1984
1985```javascript
1986import { _isArray } from './_internals/_isArray'
1987import { _isInteger } from './_internals/_isInteger'
1988import { assoc } from './assoc'
1989import { curry } from './curry'
1990
1991function assocPathFn(
1992 path, newValue, input
1993){
1994 const pathArrValue =
1995 typeof path === 'string' ?
1996 path.split('.').map(x => _isInteger(Number(x)) ? Number(x) : x) :
1997 path
1998 if (pathArrValue.length === 0){
1999 return newValue
2000 }
2001
2002 const index = pathArrValue[ 0 ]
2003 if (pathArrValue.length > 1){
2004 const condition =
2005 typeof input !== 'object' ||
2006 input === null ||
2007 !input.hasOwnProperty(index)
2008
2009 const nextinput = condition ?
2010 _isInteger(pathArrValue[ 1 ]) ?
2011 [] :
2012 {} :
2013 input[ index ]
2014
2015 newValue = assocPathFn(
2016 Array.prototype.slice.call(pathArrValue, 1),
2017 newValue,
2018 nextinput
2019 )
2020 }
2021
2022 if (_isInteger(index) && _isArray(input)){
2023 const arr = input.slice()
2024 arr[ index ] = newValue
2025
2026 return arr
2027 }
2028
2029 return assoc(
2030 index, newValue, input
2031 )
2032}
2033
2034export const assocPath = curry(assocPathFn)
2035```
2036
2037</details>
2038
2039<details>
2040
2041<summary><strong>Tests</strong></summary>
2042
2043```javascript
2044import { assocPath } from './assocPath'
2045
2046test('string can be used as path input', () => {
2047 const testObj = {
2048 a : [ { b : 1 }, { b : 2 } ],
2049 d : 3,
2050 }
2051 const result = assocPath(
2052 'a.0.b', 10, testObj
2053 )
2054 const expected = {
2055 a : [ { b : 10 }, { b : 2 } ],
2056 d : 3,
2057 }
2058 expect(result).toEqual(expected)
2059})
2060
2061test('bug', () => {
2062 /*
2063 https://github.com/selfrefactor/rambda/issues/524
2064 */
2065 const state = {}
2066
2067 const withDateLike = assocPath(
2068 [ 'outerProp', '2020-03-10' ],
2069 { prop : 2 },
2070 state
2071 )
2072 const withNumber = assocPath(
2073 [ 'outerProp', '5' ], { prop : 2 }, state
2074 )
2075
2076 const withDateLikeExpected = { outerProp : { '2020-03-10' : { prop : 2 } } }
2077 const withNumberExpected = { outerProp : { 5 : { prop : 2 } } }
2078 expect(withDateLike).toEqual(withDateLikeExpected)
2079 expect(withNumber).toEqual(withNumberExpected)
2080})
2081
2082test('adds a key to an empty object', () => {
2083 expect(assocPath(
2084 [ 'a' ], 1, {}
2085 )).toEqual({ a : 1 })
2086})
2087
2088test('adds a key to a non-empty object', () => {
2089 expect(assocPath(
2090 'b', 2, { a : 1 }
2091 )).toEqual({
2092 a : 1,
2093 b : 2,
2094 })
2095})
2096
2097test('adds a nested key to a non-empty object', () => {
2098 expect(assocPath(
2099 'b.c', 2, { a : 1 }
2100 )).toEqual({
2101 a : 1,
2102 b : { c : 2 },
2103 })
2104})
2105
2106test('adds a nested key to a nested non-empty object - curry case 1', () => {
2107 expect(assocPath('b.d',
2108 3)({
2109 a : 1,
2110 b : { c : 2 },
2111 })).toEqual({
2112 a : 1,
2113 b : {
2114 c : 2,
2115 d : 3,
2116 },
2117 })
2118})
2119
2120test('adds a key to a non-empty object - curry case 1', () => {
2121 expect(assocPath('b', 2)({ a : 1 })).toEqual({
2122 a : 1,
2123 b : 2,
2124 })
2125})
2126
2127test('adds a nested key to a non-empty object - curry case 1', () => {
2128 expect(assocPath('b.c', 2)({ a : 1 })).toEqual({
2129 a : 1,
2130 b : { c : 2 },
2131 })
2132})
2133
2134test('adds a key to a non-empty object - curry case 2', () => {
2135 expect(assocPath('b')(2, { a : 1 })).toEqual({
2136 a : 1,
2137 b : 2,
2138 })
2139})
2140
2141test('adds a key to a non-empty object - curry case 3', () => {
2142 const result = assocPath('b')(2)({ a : 1 })
2143
2144 expect(result).toEqual({
2145 a : 1,
2146 b : 2,
2147 })
2148})
2149
2150test('changes an existing key', () => {
2151 expect(assocPath(
2152 'a', 2, { a : 1 }
2153 )).toEqual({ a : 2 })
2154})
2155
2156test('undefined is considered an empty object', () => {
2157 expect(assocPath(
2158 'a', 1, undefined
2159 )).toEqual({ a : 1 })
2160})
2161
2162test('null is considered an empty object', () => {
2163 expect(assocPath(
2164 'a', 1, null
2165 )).toEqual({ a : 1 })
2166})
2167
2168test('value can be null', () => {
2169 expect(assocPath(
2170 'a', null, null
2171 )).toEqual({ a : null })
2172})
2173
2174test('value can be undefined', () => {
2175 expect(assocPath(
2176 'a', undefined, null
2177 )).toEqual({ a : undefined })
2178})
2179
2180test('assignment is shallow', () => {
2181 expect(assocPath(
2182 'a', { b : 2 }, { a : { c : 3 } }
2183 )).toEqual({ a : { b : 2 } })
2184})
2185
2186test('empty array as path', () => {
2187 const result = assocPath(
2188 [], 3, {
2189 a : 1,
2190 b : 2,
2191 }
2192 )
2193 expect(result).toEqual(3)
2194})
2195
2196test('happy', () => {
2197 const expected = { foo : { bar : { baz : 42 } } }
2198 const result = assocPath(
2199 [ 'foo', 'bar', 'baz' ], 42, { foo : null }
2200 )
2201 expect(result).toEqual(expected)
2202})
2203```
2204
2205</details>
2206
2207<details>
2208
2209<summary><strong>Typescript</strong> test</summary>
2210
2211```typescript
2212import {assocPath} from 'rambda'
2213
2214interface Output {
2215 a: number,
2216 foo: {bar: number},
2217}
2218
2219describe('R.assocPath - user must explicitly set type of output', () => {
2220 it('with array as path input', () => {
2221 const result = assocPath<Output>(['foo', 'bar'], 2, {a: 1})
2222
2223 result // $ExpectType Output
2224 })
2225 it('with string as path input', () => {
2226 const result = assocPath<Output>('foo.bar', 2, {a: 1})
2227
2228 result // $ExpectType Output
2229 })
2230})
2231
2232describe('R.assocPath - curried', () => {
2233 it('with array as path input', () => {
2234 const result = assocPath<Output>(['foo', 'bar'], 2)({a: 1})
2235
2236 result // $ExpectType Output
2237 })
2238 it('with string as path input', () => {
2239 const result = assocPath<Output>('foo.bar', 2)({a: 1})
2240
2241 result // $ExpectType Output
2242 })
2243})
2244```
2245
2246</details>
2247
2248[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#assocPath)
2249
2250### both
2251
2252```typescript
2253
2254both(pred1: Pred, pred2: Pred): Pred
2255```
2256
2257It returns a function with `input` argument.
2258
2259This function will return `true`, if both `firstCondition` and `secondCondition` return `true` when `input` is passed as their argument.
2260
2261```javascript
2262const firstCondition = x => x > 10
2263const secondCondition = x => x < 20
2264const fn = R.both(secondCondition)
2265
2266const result = [fn(15), fn(30)]
2267// => [true, false]
2268```
2269
2270<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20firstCondition%20%3D%20x%20%3D%3E%20x%20%3E%2010%0Aconst%20secondCondition%20%3D%20x%20%3D%3E%20x%20%3C%2020%0Aconst%20fn%20%3D%20R.both(secondCondition)%0A%0Aconst%20result%20%3D%20%5Bfn(15)%2C%20fn(30)%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.both</strong> example in Rambda REPL</a>
2271
2272<details>
2273
2274<summary>All Typescript definitions</summary>
2275
2276```typescript
2277both(pred1: Pred, pred2: Pred): Pred;
2278both<T>(pred1: Predicate<T>, pred2: Predicate<T>): Predicate<T>;
2279both<T>(pred1: Predicate<T>): (pred2: Predicate<T>) => Predicate<T>;
2280both(pred1: Pred): (pred2: Pred) => Pred;
2281```
2282
2283</details>
2284
2285<details>
2286
2287<summary><strong>R.both</strong> source</summary>
2288
2289```javascript
2290export function both(f, g){
2291 if (arguments.length === 1) return _g => both(f, _g)
2292
2293 return (...input) => f(...input) && g(...input)
2294}
2295```
2296
2297</details>
2298
2299<details>
2300
2301<summary><strong>Tests</strong></summary>
2302
2303```javascript
2304import { both } from './both'
2305
2306const firstFn = val => val > 0
2307const secondFn = val => val < 10
2308
2309test('with curry', () => {
2310 expect(both(firstFn)(secondFn)(17)).toBeFalse()
2311})
2312
2313test('without curry', () => {
2314 expect(both(firstFn, secondFn)(7)).toBeTrue()
2315})
2316
2317test('with multiple inputs', () => {
2318 const between = function (
2319 a, b, c
2320 ){
2321 return a < b && b < c
2322 }
2323 const total20 = function (
2324 a, b, c
2325 ){
2326 return a + b + c === 20
2327 }
2328 const fn = both(between, total20)
2329 expect(fn(
2330 5, 7, 8
2331 )).toBeTrue()
2332})
2333
2334test('skip evaluation of the second expression', () => {
2335 let effect = 'not evaluated'
2336 const F = function (){
2337 return false
2338 }
2339 const Z = function (){
2340 effect = 'Z got evaluated'
2341 }
2342 both(F, Z)()
2343
2344 expect(effect).toBe('not evaluated')
2345})
2346```
2347
2348</details>
2349
2350<details>
2351
2352<summary><strong>Typescript</strong> test</summary>
2353
2354```typescript
2355import {both} from 'rambda'
2356
2357describe('R.both', () => {
2358 it('with passed type', () => {
2359 const fn = both<number>(
2360 x => x > 1,
2361 x => x % 2 === 0
2362 )
2363 fn // $ExpectType Predicate<number>
2364 const result = fn(2) // $ExpectType boolean
2365 result // $ExpectType boolean
2366 })
2367 it('with passed type - curried', () => {
2368 const fn = both<number>(x => x > 1)(x => x % 2 === 0)
2369 fn // $ExpectType Predicate<number>
2370 const result = fn(2)
2371 result // $ExpectType boolean
2372 })
2373 it('no type passed', () => {
2374 const fn = both(
2375 x => {
2376 x // $ExpectType any
2377 return x > 1
2378 },
2379 x => {
2380 x // $ExpectType any
2381 return x % 2 === 0
2382 }
2383 )
2384 const result = fn(2)
2385 result // $ExpectType boolean
2386 })
2387 it('no type passed - curried', () => {
2388 const fn = both((x: number) => {
2389 x // $ExpectType number
2390 return x > 1
2391 })((x: number) => {
2392 x // $ExpectType number
2393 return x % 2 === 0
2394 })
2395 const result = fn(2)
2396 result // $ExpectType boolean
2397 })
2398})
2399```
2400
2401</details>
2402
2403<details>
2404
2405<summary>1 failed <italic>Ramda.both</italic> specs
2406
2407> :boom: Reason for the failure: Ramda library supports fantasy-land
2408</summary>
2409
2410```javascript
2411var S = require('sanctuary');
2412
2413var R = require('../../../../dist/rambda.js');
2414var eq = require('./shared/eq');
2415describe('both', function() {
2416 it('accepts fantasy-land applicative functors', function() {
2417 var Just = S.Just;
2418 var Nothing = S.Nothing;
2419 eq(R.both(Just(true), Just(true)), Just(true));
2420 eq(R.both(Just(true), Just(false)), Just(false));
2421 eq(R.both(Just(true), Nothing()), Nothing());
2422 eq(R.both(Nothing(), Just(false)), Nothing());
2423 eq(R.both(Nothing(), Nothing()), Nothing());
2424 });
2425});
2426```
2427
2428</details>
2429
2430[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#both)
2431
2432### chain
2433
2434```typescript
2435
2436chain<T, U>(fn: (n: T) => U[], list: readonly T[]): U[]
2437```
2438
2439The method is also known as `flatMap`.
2440
2441```javascript
2442const duplicate = n => [ n, n ]
2443const list = [ 1, 2, 3 ]
2444
2445const result = chain(duplicate, list)
2446// => [ 1, 1, 2, 2, 3, 3 ]
2447```
2448
2449<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20duplicate%20%3D%20n%20%3D%3E%20%5B%20n%2C%20n%20%5D%0Aconst%20list%20%3D%20%5B%201%2C%202%2C%203%20%5D%0A%0Aconst%20result%20%3D%20chain(duplicate%2C%20list)%0A%2F%2F%20%3D%3E%20%5B%201%2C%201%2C%202%2C%202%2C%203%2C%203%20%5D">Try this <strong>R.chain</strong> example in Rambda REPL</a>
2450
2451<details>
2452
2453<summary>All Typescript definitions</summary>
2454
2455```typescript
2456chain<T, U>(fn: (n: T) => U[], list: readonly T[]): U[];
2457chain<T, U>(fn: (n: T) => U[]): (list: readonly T[]) => U[];
2458chain<X0, X1, R>(fn: (x0: X0, x1: X1) => R, fn1: (x1: X1) => X0): (x1: X1) => R;
2459```
2460
2461</details>
2462
2463<details>
2464
2465<summary><strong>R.chain</strong> source</summary>
2466
2467```javascript
2468export function chain(fn, list){
2469 if (arguments.length === 1){
2470 return _list => chain(fn, _list)
2471 }
2472
2473 return [].concat(...list.map(fn))
2474}
2475```
2476
2477</details>
2478
2479<details>
2480
2481<summary><strong>Tests</strong></summary>
2482
2483```javascript
2484import { chain } from './chain'
2485
2486const duplicate = n => [ n, n ]
2487
2488test('happy', () => {
2489 const fn = x => [ x * 2 ]
2490 const list = [ 1, 2, 3 ]
2491
2492 const result = chain(fn, list)
2493
2494 expect(result).toEqual([ 2, 4, 6 ])
2495})
2496
2497test('maps then flattens one level', () => {
2498 expect(chain(duplicate, [ 1, 2, 3 ])).toEqual([ 1, 1, 2, 2, 3, 3 ])
2499})
2500
2501test('maps then flattens one level - curry', () => {
2502 expect(chain(duplicate)([ 1, 2, 3 ])).toEqual([ 1, 1, 2, 2, 3, 3 ])
2503})
2504
2505test('flattens only one level', () => {
2506 const nest = n => [ [ n ] ]
2507 expect(chain(nest, [ 1, 2, 3 ])).toEqual([ [ 1 ], [ 2 ], [ 3 ] ])
2508})
2509```
2510
2511</details>
2512
2513<details>
2514
2515<summary><strong>Typescript</strong> test</summary>
2516
2517```typescript
2518import {chain} from 'rambda'
2519
2520const list = [1, 2, 3]
2521const fn = (x: number) => [`${x}`, `${x}`]
2522
2523describe('R.chain', () => {
2524 it('without passing type', () => {
2525 const result = chain(fn, list)
2526 result // $ExpectType string[]
2527 const resultCurried = chain(fn)(list)
2528 resultCurried // $ExpectType string[]
2529 })
2530})
2531```
2532
2533</details>
2534
2535*5 failed Ramda.chain specs*
2536
2537> :boom: Reason for the failure: Ramda method passes to `chain` property if available | Ramda library supports fantasy-land
2538
2539[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#chain)
2540
2541### clamp
2542
2543```typescript
2544
2545clamp(min: number, max: number, input: number): number
2546```
2547
2548Restrict a number `input` to be withing `min` and `max` limits.
2549
2550If `input` is bigger than `max`, then the result is `max`.
2551
2552If `input` is smaller than `min`, then the result is `min`.
2553
2554```javascript
2555R.clamp(0, 10, 5) //=> 5
2556R.clamp(0, 10, -1) //=> 0
2557R.clamp(0, 10, 11) //=> 10
2558```
2559
2560<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.clamp(0%2C%2010%2C%205)%20%2F%2F%3D%3E%205%0AR.clamp(0%2C%2010%2C%20-1)%20%2F%2F%3D%3E%200%0AR.clamp(0%2C%2010%2C%2011)%20%2F%2F%3D%3E%2010">Try this <strong>R.clamp</strong> example in Rambda REPL</a>
2561
2562<details>
2563
2564<summary>All Typescript definitions</summary>
2565
2566```typescript
2567clamp(min: number, max: number, input: number): number;
2568clamp(min: number, max: number): (input: number) => number;
2569```
2570
2571</details>
2572
2573<details>
2574
2575<summary><strong>R.clamp</strong> source</summary>
2576
2577```javascript
2578import { curry } from './curry'
2579
2580function clampFn(
2581 min, max, input
2582){
2583 if (min > max){
2584 throw new Error('min must not be greater than max in clamp(min, max, value)')
2585 }
2586 if (input >= min && input <= max) return input
2587
2588 if (input > max) return max
2589 if (input < min) return min
2590}
2591
2592export const clamp = curry(clampFn)
2593```
2594
2595</details>
2596
2597<details>
2598
2599<summary><strong>Tests</strong></summary>
2600
2601```javascript
2602import { clamp } from './clamp'
2603
2604test('when min is greater than max', () => {
2605 expect(() => clamp(
2606 -5, -10, 5
2607 )).toThrowWithMessage(Error,
2608 'min must not be greater than max in clamp(min, max, value)')
2609})
2610
2611test('rambda specs', () => {
2612 expect(clamp(
2613 1, 10, 0
2614 )).toEqual(1)
2615 expect(clamp(
2616 3, 12, 1
2617 )).toEqual(3)
2618 expect(clamp(
2619 -15, 3, -100
2620 )).toEqual(-15)
2621 expect(clamp(
2622 1, 10, 20
2623 )).toEqual(10)
2624 expect(clamp(
2625 3, 12, 23
2626 )).toEqual(12)
2627 expect(clamp(
2628 -15, 3, 16
2629 )).toEqual(3)
2630 expect(clamp(
2631 1, 10, 4
2632 )).toEqual(4)
2633 expect(clamp(
2634 3, 12, 6
2635 )).toEqual(6)
2636 expect(clamp(
2637 -15, 3, 0
2638 )).toEqual(0)
2639})
2640```
2641
2642</details>
2643
2644<details>
2645
2646<summary><strong>Typescript</strong> test</summary>
2647
2648```typescript
2649import {clamp} from 'rambda'
2650
2651describe('R.clamp', () => {
2652 it('happy', () => {
2653 const result = clamp(1, 10, 20)
2654 result // $ExpectType number
2655 })
2656})
2657```
2658
2659</details>
2660
2661[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#clamp)
2662
2663### clone
2664
2665```typescript
2666
2667clone<T>(input: T): T
2668```
2669
2670It creates a deep copy of the `input`, which may contain (nested) Arrays and Objects, Numbers, Strings, Booleans and Dates.
2671
2672```javascript
2673const objects = [{a: 1}, {b: 2}];
2674const objectsClone = R.clone(objects);
2675
2676const result = [
2677 R.equals(objects, objectsClone),
2678 R.equals(objects[0], objectsClone[0]),
2679] // => [ true, true ]
2680```
2681
2682<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20objects%20%3D%20%5B%7Ba%3A%201%7D%2C%20%7Bb%3A%202%7D%5D%3B%0Aconst%20objectsClone%20%3D%20R.clone(objects)%3B%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.equals(objects%2C%20objectsClone)%2C%0A%20%20R.equals(objects%5B0%5D%2C%20objectsClone%5B0%5D)%2C%0A%5D%20%2F%2F%20%3D%3E%20%5B%20true%2C%20true%20%5D">Try this <strong>R.clone</strong> example in Rambda REPL</a>
2683
2684<details>
2685
2686<summary>All Typescript definitions</summary>
2687
2688```typescript
2689clone<T>(input: T): T;
2690clone<T>(input: readonly T[]): T[];
2691```
2692
2693</details>
2694
2695<details>
2696
2697<summary><strong>R.clone</strong> source</summary>
2698
2699```javascript
2700import { _isArray } from './_internals/_isArray'
2701
2702export function clone(input){
2703 const out = _isArray(input) ? Array(input.length) : {}
2704 if (input && input.getTime) return new Date(input.getTime())
2705
2706 for (const key in input){
2707 const v = input[ key ]
2708 out[ key ] =
2709 typeof v === 'object' && v !== null ?
2710 v.getTime ?
2711 new Date(v.getTime()) :
2712 clone(v) :
2713 v
2714 }
2715
2716 return out
2717}
2718```
2719
2720</details>
2721
2722<details>
2723
2724<summary><strong>Tests</strong></summary>
2725
2726```javascript
2727import assert from 'assert'
2728
2729import { clone } from './clone'
2730import { equals } from './equals'
2731
2732test('with array', () => {
2733 const arr = [
2734 {
2735 b : 2,
2736 c : 'foo',
2737 d : [ 1, 2, 3 ],
2738 },
2739 1,
2740 new Date(),
2741 null,
2742 ]
2743 expect(clone(arr)).toEqual(arr)
2744})
2745
2746test('with object', () => {
2747 const obj = {
2748 a : 1,
2749 b : 2,
2750 c : 3,
2751 d : [ 1, 2, 3 ],
2752 e : new Date(),
2753 }
2754 expect(clone(obj)).toEqual(obj)
2755})
2756
2757test('with date', () => {
2758 const date = new Date(
2759 2014, 10, 14, 23, 59, 59, 999
2760 )
2761
2762 const cloned = clone(date)
2763 assert.notStrictEqual(date, cloned)
2764 expect(cloned).toEqual(new Date(
2765 2014, 10, 14, 23, 59, 59, 999
2766 ))
2767
2768 expect(cloned.getDay()).toEqual(5)
2769})
2770
2771test('with R.equals', () => {
2772 const objects = [ { a : 1 }, { b : 2 } ]
2773
2774 const objectsClone = clone(objects)
2775
2776 const result = [
2777 equals(objects, objectsClone),
2778 equals(objects[ 0 ], objectsClone[ 0 ]),
2779 ]
2780 expect(result).toEqual([ true, true ])
2781})
2782```
2783
2784</details>
2785
2786<details>
2787
2788<summary><strong>Typescript</strong> test</summary>
2789
2790```typescript
2791import {clone} from 'rambda'
2792
2793describe('R.clone', () => {
2794 it('happy', () => {
2795 const obj = {a: 1, b: 2}
2796 const result = clone(obj)
2797 result // $ExpectType { a: number; b: number; }
2798 })
2799})
2800```
2801
2802</details>
2803
2804<details>
2805
2806<summary>9 failed <italic>Ramda.clone</italic> specs
2807
2808> :boom: Reason for the failure: Rambda method work only with objects and arrays
2809</summary>
2810
2811```javascript
2812var assert = require('assert');
2813
2814var R = require('../../../../dist/rambda.js');
2815var eq = require('./shared/eq');
2816describe('deep clone integers, strings and booleans', function() {
2817 it('clones integers', function() {
2818 eq(R.clone(-4), -4);
2819 eq(R.clone(9007199254740991), 9007199254740991);
2820 });
2821 it('clones floats', function() {
2822 eq(R.clone(-4.5), -4.5);
2823 eq(R.clone(0.0), 0.0);
2824 });
2825 it('clones strings', function() {
2826 eq(R.clone('ramda'), 'ramda');
2827 });
2828 it('clones booleans', function() {
2829 eq(R.clone(true), true);
2830 });
2831});
2832describe('deep clone objects', function() {
2833 it('clones objects with circular references', function() {
2834 var x = {c: null};
2835 var y = {a: x};
2836 var z = {b: y};
2837 x.c = z;
2838 var clone = R.clone(x);
2839 assert.notStrictEqual(x, clone);
2840 assert.notStrictEqual(x.c, clone.c);
2841 assert.notStrictEqual(x.c.b, clone.c.b);
2842 assert.notStrictEqual(x.c.b.a, clone.c.b.a);
2843 assert.notStrictEqual(x.c.b.a.c, clone.c.b.a.c);
2844 eq(R.keys(clone), R.keys(x));
2845 eq(R.keys(clone.c), R.keys(x.c));
2846 eq(R.keys(clone.c.b), R.keys(x.c.b));
2847 eq(R.keys(clone.c.b.a), R.keys(x.c.b.a));
2848 eq(R.keys(clone.c.b.a.c), R.keys(x.c.b.a.c));
2849 x.c.b = 1;
2850 assert.notDeepEqual(clone.c.b, x.c.b);
2851 });
2852});
2853describe('deep clone arrays', function() {
2854});
2855describe('deep clone functions', function() {
2856});
2857describe('built-in types', function() {
2858 it('clones RegExp object', function() {
2859 R.forEach(function(pattern) {
2860 var clone = R.clone(pattern);
2861 assert.notStrictEqual(clone, pattern);
2862 eq(clone.constructor, RegExp);
2863 eq(clone.source, pattern.source);
2864 eq(clone.global, pattern.global);
2865 eq(clone.ignoreCase, pattern.ignoreCase);
2866 eq(clone.multiline, pattern.multiline);
2867 }, [/x/, /x/g, /x/i, /x/m, /x/gi, /x/gm, /x/im, /x/gim]);
2868 });
2869});
2870describe('deep clone deep nested mixed objects', function() {
2871 it('clones array with mutual ref object', function() {
2872 var obj = {a: 1};
2873 var list = [{b: obj}, {b: obj}];
2874 var clone = R.clone(list);
2875 assert.strictEqual(list[0].b, list[1].b);
2876 assert.strictEqual(clone[0].b, clone[1].b);
2877 assert.notStrictEqual(clone[0].b, list[0].b);
2878 assert.notStrictEqual(clone[1].b, list[1].b);
2879 eq(clone[0].b, {a:1});
2880 eq(clone[1].b, {a:1});
2881 obj.a = 2;
2882 eq(clone[0].b, {a:1});
2883 eq(clone[1].b, {a:1});
2884 });
2885});
2886describe('deep clone edge cases', function() {
2887 it('nulls, undefineds and empty objects and arrays', function() {
2888 eq(R.clone(null), null);
2889 eq(R.clone(undefined), undefined);
2890 assert.notStrictEqual(R.clone(undefined), null);
2891 var obj = {};
2892 assert.notStrictEqual(R.clone(obj), obj);
2893 var list = [];
2894 assert.notStrictEqual(R.clone(list), list);
2895 });
2896});
2897describe('Let `R.clone` use an arbitrary user defined `clone` method', function() {
2898 it('dispatches to `clone` method if present', function() {
2899 function ArbitraryClone(x) { this.value = x; }
2900 ArbitraryClone.prototype.clone = function() { return new ArbitraryClone(this.value); };
2901 var obj = new ArbitraryClone(42);
2902 var arbitraryClonedObj = R.clone(obj);
2903 eq(arbitraryClonedObj, new ArbitraryClone(42));
2904 eq(arbitraryClonedObj instanceof ArbitraryClone, true);
2905 });
2906});
2907```
2908
2909</details>
2910
2911[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#clone)
2912
2913### complement
2914
2915```typescript
2916
2917complement(pred: (...args: readonly any[]) => boolean): (...args: readonly any[]) => boolean
2918```
2919
2920It returns `inverted` version of `origin` function that accept `input` as argument.
2921
2922The return value of `inverted` is the negative boolean value of `origin(input)`.
2923
2924```javascript
2925const origin = x => x > 5
2926const inverted = complement(origin)
2927
2928const result = [
2929 origin(7),
2930 inverted(7)
2931] => [ true, false ]
2932```
2933
2934<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20origin%20%3D%20x%20%3D%3E%20x%20%3E%205%0Aconst%20inverted%20%3D%20complement(origin)%0A%0Aconst%20result%20%3D%20%5B%0A%20%20origin(7)%2C%0A%20%20inverted(7)%0A%5D%20%3D%3E%20%5B%20true%2C%20false%20%5D">Try this <strong>R.complement</strong> example in Rambda REPL</a>
2935
2936<details>
2937
2938<summary>All Typescript definitions</summary>
2939
2940```typescript
2941complement(pred: (...args: readonly any[]) => boolean): (...args: readonly any[]) => boolean;
2942```
2943
2944</details>
2945
2946<details>
2947
2948<summary><strong>R.complement</strong> source</summary>
2949
2950```javascript
2951export function complement(fn){
2952 return (...input) => !fn(...input)
2953}
2954```
2955
2956</details>
2957
2958<details>
2959
2960<summary><strong>Tests</strong></summary>
2961
2962```javascript
2963import { complement } from './complement'
2964
2965test('happy', () => {
2966 const fn = complement(x => x.length === 0)
2967
2968 expect(fn([ 1, 2, 3 ])).toBeTrue()
2969})
2970
2971test('with multiple parameters', () => {
2972 const between = function (
2973 a, b, c
2974 ){
2975 return a < b && b < c
2976 }
2977 const f = complement(between)
2978 expect(f(
2979 4, 5, 11
2980 )).toEqual(false)
2981 expect(f(
2982 12, 2, 6
2983 )).toEqual(true)
2984})
2985```
2986
2987</details>
2988
2989<details>
2990
2991<summary><strong>Typescript</strong> test</summary>
2992
2993```typescript
2994import {complement, isNil} from 'rambda'
2995
2996describe('R.complement', () => {
2997 it('happy', () => {
2998 const fn = complement(isNil)
2999 const result = fn(null)
3000 result // $ExpectType boolean
3001 })
3002})
3003```
3004
3005</details>
3006
3007<details>
3008
3009<summary>1 failed <italic>Ramda.complement</italic> specs
3010
3011> :boom: Reason for the failure: Ramda library supports fantasy-land
3012</summary>
3013
3014```javascript
3015var S = require('sanctuary');
3016
3017var R = require('../../../../dist/rambda.js');
3018var eq = require('./shared/eq');
3019describe('complement', function() {
3020 it('accepts fantasy-land functors', function() {
3021 var Just = S.Just;
3022 var Nothing = S.Nothing;
3023 eq(R.complement(Just(true)), Just(false));
3024 eq(R.complement(Just(false)), Just(true));
3025 eq(R.complement(Nothing()), Nothing());
3026 });
3027});
3028```
3029
3030</details>
3031
3032[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#complement)
3033
3034### compose
3035
3036```typescript
3037
3038compose<T1>(fn0: () => T1): () => T1
3039```
3040
3041It performs right-to-left function composition.
3042
3043```javascript
3044const result = R.compose(
3045 R.map(x => x * 2),
3046 R.filter(x => x > 2)
3047)([1, 2, 3, 4])
3048
3049// => [6, 8]
3050```
3051
3052<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.compose(%0A%20%20R.map(x%20%3D%3E%20x%20*%202)%2C%0A%20%20R.filter(x%20%3D%3E%20x%20%3E%202)%0A)(%5B1%2C%202%2C%203%2C%204%5D)%0A%0A%2F%2F%20%3D%3E%20%5B6%2C%208%5D">Try this <strong>R.compose</strong> example in Rambda REPL</a>
3053
3054<details>
3055
3056<summary>All Typescript definitions</summary>
3057
3058```typescript
3059compose<T1>(fn0: () => T1): () => T1;
3060compose<V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1;
3061compose<V0, V1, T1>(fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T1;
3062compose<V0, V1, V2, T1>(fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T1;
3063
3064compose<T1, T2>(fn1: (x: T1) => T2, fn0: () => T1): () => T2;
3065compose<V0, T1, T2>(fn1: (x: T1) => T2, fn0: (x0: V0) => T1): (x0: V0) => T2;
3066compose<V0, V1, T1, T2>(fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T2;
3067compose<V0, V1, V2, T1, T2>(fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T2;
3068
3069compose<T1, T2, T3>(fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: () => T1): () => T3;
3070compose<V0, T1, T2, T3>(fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x: V0) => T1): (x: V0) => T3;
3071compose<V0, V1, T1, T2, T3>(fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T3;
3072compose<V0, V1, V2, T1, T2, T3>(fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T3;
3073
3074compose<T1, T2, T3, T4>(fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: () => T1): () => T4;
3075compose<V0, T1, T2, T3, T4>(fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x: V0) => T1): (x: V0) => T4;
3076compose<V0, V1, T1, T2, T3, T4>(fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T4;
3077compose<V0, V1, V2, T1, T2, T3, T4>(fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T4;
3078
3079compose<T1, T2, T3, T4, T5>(fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: () => T1): () => T5;
3080compose<V0, T1, T2, T3, T4, T5>(fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x: V0) => T1): (x: V0) => T5;
3081compose<V0, V1, T1, T2, T3, T4, T5>(fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T5;
3082compose<V0, V1, V2, T1, T2, T3, T4, T5>(fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T5;
3083
3084compose<T1, T2, T3, T4, T5, T6>(fn5: (x: T5) => T6, fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: () => T1): () => T6;
3085compose<V0, T1, T2, T3, T4, T5, T6>(fn5: (x: T5) => T6, fn4: (x: T4) => T5, fn3: (x: T3) => T4, fn2: (x: T2) => T3, fn1: (x: T1) => T2, fn0: (x: V0) => T1): (x: V0) => T6;
3086compose<V0, V1, T1, T2, T3, T4, T5, T6>(
3087 fn5: (x: T5) => T6,
3088 fn4: (x: T4) => T5,
3089 fn3: (x: T3) => T4,
3090 fn2: (x: T2) => T3,
3091 fn1: (x: T1) => T2,
3092 fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T6;
3093compose<V0, V1, V2, T1, T2, T3, T4, T5, T6>(
3094 fn5: (x: T5) => T6,
3095 fn4: (x: T4) => T5,
3096 fn3: (x: T3) => T4,
3097 fn2: (x: T2) => T3,
3098 fn1: (x: T1) => T2,
3099 fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T6;
3100```
3101
3102</details>
3103
3104<details>
3105
3106<summary><strong>R.compose</strong> source</summary>
3107
3108```javascript
3109export function compose(...fns){
3110 if (fns.length === 0){
3111 throw new Error('compose requires at least one argument')
3112 }
3113
3114 return (...args) => {
3115 const list = fns.slice()
3116 if (list.length > 0){
3117 const fn = list.pop()
3118 let result = fn(...args)
3119 while (list.length > 0){
3120 result = list.pop()(result)
3121 }
3122
3123 return result
3124 }
3125 }
3126}
3127```
3128
3129</details>
3130
3131<details>
3132
3133<summary><strong>Tests</strong></summary>
3134
3135```javascript
3136import { add } from './add'
3137import { compose } from './compose'
3138import { filter } from './filter'
3139import { last } from './last'
3140import { map } from './map'
3141
3142test('happy', () => {
3143 const result = compose(
3144 last, map(add(10)), map(add(1))
3145 )([ 1, 2, 3 ])
3146
3147 expect(result).toEqual(14)
3148})
3149
3150test('can accepts initially two arguments', () => {
3151 const result = compose(map(x => x * 2),
3152 (list, limit) => filter(x => x > limit, list))([ 1, 2, 3, 4, false ], 2)
3153
3154 expect(result).toEqual([ 6, 8 ])
3155})
3156
3157test('when no arguments is passed', () => {
3158 expect(() => compose()).toThrow('compose requires at least one argument')
3159})
3160
3161test('ramda spec', () => {
3162 const f = function (
3163 a, b, c
3164 ){
3165 return [ a, b, c ]
3166 }
3167 const g = compose(f)
3168
3169 expect(g(
3170 1, 2, 3
3171 )).toEqual([ 1, 2, 3 ])
3172})
3173```
3174
3175</details>
3176
3177<details>
3178
3179<summary><strong>Typescript</strong> test</summary>
3180
3181```typescript
3182import {add, subtract, compose} from 'rambda'
3183
3184describe('R.compose', () => {
3185 it('happy', () => {
3186 const result = compose(subtract(11), add(1), add(1))(1)
3187 result // $ExpectType number
3188 })
3189
3190 it('with void', () => {
3191 const result = compose(
3192 () => {},
3193 () => {}
3194 )()
3195 result // $ExpectType void
3196 })
3197})
3198```
3199
3200</details>
3201
3202<details>
3203
3204<summary>3 failed <italic>Ramda.compose</italic> specs
3205
3206> :boom: Reason for the failure: Ramda method passes context to functions | Rambda composed functions have no length
3207</summary>
3208
3209```javascript
3210var assert = require('assert');
3211var jsv = require('jsverify');
3212
3213var R = require('../../../../dist/rambda.js');
3214var eq = require('./shared/eq');
3215describe('compose', function() {
3216 it('performs right-to-left function composition', function() {
3217 // f :: (String, Number?) -> ([Number] -> [Number])
3218 var f = R.compose(R.map, R.multiply, parseInt);
3219 eq(f.length, 2);
3220 eq(f('10')([1, 2, 3]), [10, 20, 30]);
3221 eq(f('10', 2)([1, 2, 3]), [2, 4, 6]);
3222 });
3223 it('passes context to functions', function() {
3224 function x(val) {
3225 return this.x * val;
3226 }
3227 function y(val) {
3228 return this.y * val;
3229 }
3230 function z(val) {
3231 return this.z * val;
3232 }
3233 var context = {
3234 a: R.compose(x, y, z),
3235 x: 4,
3236 y: 2,
3237 z: 1
3238 };
3239 eq(context.a(5), 40);
3240 });
3241 it('can be applied to one argument', function() {
3242 var f = function(a, b, c) { return [a, b, c]; };
3243 var g = R.compose(f);
3244 eq(g.length, 3);
3245 eq(g(1, 2, 3), [1, 2, 3]);
3246 });
3247});
3248describe('compose properties', function() {
3249 jsv.property('composes two functions', jsv.fn(), jsv.fn(), jsv.nat, function(f, g, x) {
3250 return R.equals(R.compose(f, g)(x), f(g(x)));
3251 jsv.property('associative', jsv.fn(), jsv.fn(), jsv.fn(), jsv.nat, function(f, g, h, x) {
3252 var result = f(g(h(x)));
3253 return R.all(R.equals(result), [
3254 R.compose(f, g, h)(x),
3255 R.compose(f, R.compose(g, h))(x),
3256 R.compose(R.compose(f, g), h)(x)
3257 ]);
3258});
3259```
3260
3261</details>
3262
3263[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#compose)
3264
3265### concat
3266
3267```typescript
3268
3269concat<T>(x: readonly T[], y: readonly T[]): T[]
3270```
3271
3272It returns a new string or array, which is the result of merging `x` and `y`.
3273
3274```javascript
3275R.concat([1, 2])([3, 4]) // => [1, 2, 3, 4]
3276R.concat('foo', 'bar') // => 'foobar'
3277```
3278
3279<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.concat(%5B1%2C%202%5D)(%5B3%2C%204%5D)%20%2F%2F%20%3D%3E%20%5B1%2C%202%2C%203%2C%204%5D%0AR.concat('foo'%2C%20'bar')%20%2F%2F%20%3D%3E%20'foobar'">Try this <strong>R.concat</strong> example in Rambda REPL</a>
3280
3281<details>
3282
3283<summary>All Typescript definitions</summary>
3284
3285```typescript
3286concat<T>(x: readonly T[], y: readonly T[]): T[];
3287concat<T>(x: readonly T[]): (y: readonly T[]) => T[];
3288concat(x: string, y: string): string;
3289concat(x: string): (y: string) => string;
3290```
3291
3292</details>
3293
3294<details>
3295
3296<summary><strong>R.concat</strong> source</summary>
3297
3298```javascript
3299export function concat(x, y){
3300 if (arguments.length === 1) return _y => concat(x, _y)
3301
3302 return typeof x === 'string' ? `${ x }${ y }` : [ ...x, ...y ]
3303}
3304```
3305
3306</details>
3307
3308<details>
3309
3310<summary><strong>Tests</strong></summary>
3311
3312```javascript
3313import { concat } from './concat'
3314
3315test('happy', () => {
3316 const arr1 = [ 'a', 'b', 'c' ]
3317 const arr2 = [ 'd', 'e', 'f' ]
3318
3319 const a = concat(arr1, arr2)
3320 const b = concat(arr1)(arr2)
3321 const expectedResult = [ 'a', 'b', 'c', 'd', 'e', 'f' ]
3322
3323 expect(a).toEqual(expectedResult)
3324 expect(b).toEqual(expectedResult)
3325})
3326
3327test('with strings', () => {
3328 expect(concat('ABC', 'DEF')).toEqual('ABCDEF')
3329})
3330```
3331
3332</details>
3333
3334<details>
3335
3336<summary><strong>Typescript</strong> test</summary>
3337
3338```typescript
3339import {concat} from 'rambda'
3340
3341const list1 = [1, 2, 3]
3342const list2 = [4, 5, 6]
3343
3344describe('R.concat', () => {
3345 it('happy', () => {
3346 const result = concat(list1, list2)
3347
3348 result // $ExpectType number[]
3349 })
3350 it('curried', () => {
3351 const result = concat(list1)(list2)
3352
3353 result // $ExpectType number[]
3354 })
3355})
3356```
3357
3358</details>
3359
3360<details>
3361
3362<summary>1 failed <italic>Ramda.concat</italic> specs
3363
3364> :boom: Reason for the failure: Ramda method pass to `concat` property if present
3365</summary>
3366
3367```javascript
3368var assert = require('assert');
3369
3370var R = require('../../../../dist/rambda.js');
3371var eq = require('./shared/eq');
3372describe('concat', function() {
3373 var z1 = {
3374 x: 'z1',
3375 concat: function(that) { return this.x + ' ' + that.x; }
3376 };
3377 var z2 = {
3378 x: 'z2'
3379 };
3380 it('delegates to non-String object with a concat method, as second param', function() {
3381 eq(R.concat(z1, z2), 'z1 z2');
3382 });
3383});
3384```
3385
3386</details>
3387
3388[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#concat)
3389
3390### cond
3391
3392```typescript
3393
3394cond(conditions: [Pred, (...a: readonly any[]) => any][]): (...x: readonly any[]) => any
3395```
3396
3397It takes list with `conditions` and returns a new function `fn` that expects `input` as argument.
3398
3399This function will start evaluating the `conditions` in order to find the first winner(order of conditions matter).
3400
3401The winner is this condition, which left side returns `true` when `input` is its argument. Then the evaluation of the right side of the winner will be the final result.
3402
3403If no winner is found, then `fn` returns `undefined`.
3404
3405```javascript
3406const fn = R.cond([
3407 [ x => x > 25, R.always('more than 25') ],
3408 [ x => x > 15, R.always('more than 15') ],
3409 [ R.T, x => `${x} is nothing special` ],
3410])
3411
3412const result = [
3413 fn(30),
3414 fn(20),
3415 fn(10),
3416]
3417// => ['more than 25', 'more than 15', '10 is nothing special']
3418```
3419
3420<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20R.cond(%5B%0A%20%20%5B%20x%20%3D%3E%20x%20%3E%2025%2C%20R.always('more%20than%2025')%20%5D%2C%0A%20%20%5B%20x%20%3D%3E%20x%20%3E%2015%2C%20R.always('more%20than%2015')%20%5D%2C%0A%20%20%5B%20R.T%2C%20x%20%3D%3E%20%60%24%7Bx%7D%20is%20nothing%20special%60%20%5D%2C%0A%5D)%0A%0Aconst%20result%20%3D%20%5B%0A%20%20fn(30)%2C%0A%20%20fn(20)%2C%0A%20%20fn(10)%2C%0A%5D%20%0A%2F%2F%20%3D%3E%20%5B'more%20than%2025'%2C%20'more%20than%2015'%2C%20'10%20is%20nothing%20special'%5D">Try this <strong>R.cond</strong> example in Rambda REPL</a>
3421
3422<details>
3423
3424<summary>All Typescript definitions</summary>
3425
3426```typescript
3427cond(conditions: [Pred, (...a: readonly any[]) => any][]): (...x: readonly any[]) => any;
3428cond<A, B>(conditions: [SafePred<A>, (...a: readonly A[]) => B][]): (...x: readonly A[]) => B;
3429```
3430
3431</details>
3432
3433<details>
3434
3435<summary><strong>R.cond</strong> source</summary>
3436
3437```javascript
3438export function cond(conditions){
3439 return input => {
3440 let done = false
3441 let toReturn
3442 conditions.forEach(([ predicate, resultClosure ]) => {
3443 if (!done && predicate(input)){
3444 done = true
3445 toReturn = resultClosure(input)
3446 }
3447 })
3448
3449 return toReturn
3450 }
3451}
3452```
3453
3454</details>
3455
3456<details>
3457
3458<summary><strong>Tests</strong></summary>
3459
3460```javascript
3461import { always } from './always'
3462import { cond } from './cond'
3463import { equals } from './equals'
3464import { T } from './T'
3465
3466test('returns a function', () => {
3467 expect(typeof cond([])).toEqual('function')
3468})
3469
3470test('returns a conditional function', () => {
3471 const fn = cond([
3472 [ equals(0), always('water freezes at 0°C') ],
3473 [ equals(100), always('water boils at 100°C') ],
3474 [
3475 T,
3476 function (temp){
3477 return 'nothing special happens at ' + temp + '°C'
3478 },
3479 ],
3480 ])
3481 expect(fn(0)).toEqual('water freezes at 0°C')
3482 expect(fn(50)).toEqual('nothing special happens at 50°C')
3483 expect(fn(100)).toEqual('water boils at 100°C')
3484})
3485
3486test('no winner', () => {
3487 const fn = cond([
3488 [ equals('foo'), always(1) ],
3489 [ equals('bar'), always(2) ],
3490 ])
3491 expect(fn('quux')).toEqual(undefined)
3492})
3493
3494test('predicates are tested in order', () => {
3495 const fn = cond([
3496 [ T, always('foo') ],
3497 [ T, always('bar') ],
3498 [ T, always('baz') ],
3499 ])
3500 expect(fn()).toEqual('foo')
3501})
3502```
3503
3504</details>
3505
3506<details>
3507
3508<summary><strong>Typescript</strong> test</summary>
3509
3510```typescript
3511import {cond, always, equals} from 'rambda'
3512
3513describe('R.cond', () => {
3514 it('happy', () => {
3515 const fn = cond<number, string>([
3516 [equals(0), always('water freezes at 0°C')],
3517 [equals(100), always('water boils at 100°C')],
3518 [
3519 () => true,
3520 function(temp) {
3521 return 'nothing special happens at ' + temp + '°C'
3522 },
3523 ],
3524 ])
3525
3526 const result = fn(0)
3527 result // $ExpectType string
3528 })
3529})
3530```
3531
3532</details>
3533
3534<details>
3535
3536<summary>2 failed <italic>Ramda.cond</italic> specs
3537
3538> :boom: Reason for the failure: pass to transformer is not applied in Rambda method
3539</summary>
3540
3541```javascript
3542var R = require('../../../../dist/rambda.js');
3543var eq = require('./shared/eq');
3544
3545describe('cond', function() {
3546 it('forwards all arguments to predicates and to transformers', function() {
3547 var fn = R.cond([
3548 [function(_, x) { return x === 42; }, function() { return arguments.length; }]
3549 ]);
3550 eq(fn(21, 42, 84), 3);
3551 });
3552 it('retains highest predicate arity', function() {
3553 var fn = R.cond([
3554 [R.nAry(2, R.T), R.T],
3555 [R.nAry(3, R.T), R.T],
3556 [R.nAry(1, R.T), R.T]
3557 ]);
3558 eq(fn.length, 3);
3559 });
3560});
3561```
3562
3563</details>
3564
3565[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#cond)
3566
3567### converge
3568
3569```typescript
3570
3571converge(after: ((...a: any[]) => any), fns: Array<((...x: any[]) => any)>): (...y: any[]) => any
3572```
3573
3574Accepts a converging function and a list of branching functions and returns a new function. When invoked, this new function is applied to some arguments, each branching function is applied to those same arguments. The results of each branching function are passed as arguments to the converging function to produce the return value.
3575
3576> :boom: Explanation is taken from `Ramda` documentation
3577
3578```javascript
3579const result = R.converge(R.multiply)([ R.add(1), R.add(3) ])(2)
3580// => 15
3581```
3582
3583<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.converge(R.multiply)(%5B%20R.add(1)%2C%20R.add(3)%20%5D)(2)%0A%2F%2F%20%3D%3E%2015">Try this <strong>R.converge</strong> example in Rambda REPL</a>
3584
3585<details>
3586
3587<summary>All Typescript definitions</summary>
3588
3589```typescript
3590converge(after: ((...a: any[]) => any), fns: Array<((...x: any[]) => any)>): (...y: any[]) => any;
3591```
3592
3593</details>
3594
3595<details>
3596
3597<summary><strong>R.converge</strong> source</summary>
3598
3599```javascript
3600import { curryN } from './curryN'
3601import { map } from './map'
3602import { max } from './max'
3603import { reduce } from './reduce'
3604
3605export function converge(fn, transformers){
3606 if (arguments.length === 1)
3607 return _transformers => converge(fn, _transformers)
3608
3609 const highestArity = reduce(
3610 (a, b) => max(a, b.length), 0, transformers
3611 )
3612
3613 return curryN(highestArity, function (){
3614 return fn.apply(this,
3615 map(g => g.apply(this, arguments), transformers))
3616 })
3617}
3618```
3619
3620</details>
3621
3622<details>
3623
3624<summary><strong>Tests</strong></summary>
3625
3626```javascript
3627import { add } from './add'
3628import { converge } from './converge'
3629import { multiply } from './multiply'
3630
3631const f1 = converge(multiply, [ a => a + 1, a => a + 10 ])
3632const f2 = converge(multiply, [ a => a + 1, (a, b) => a + b + 10 ])
3633const f3 = converge(multiply, [ a => a + 1, (
3634 a, b, c
3635) => a + b + c + 10 ])
3636
3637test('happy', () => {
3638 expect(f2(6, 7)).toEqual(161)
3639})
3640
3641test('passes the results of applying the arguments individually', () => {
3642 const result = converge(multiply)([ add(1), add(3) ])(2)
3643 expect(result).toEqual(15)
3644})
3645
3646test('returns a function with the length of the longest argument', () => {
3647 expect(f1.length).toEqual(1)
3648 expect(f2.length).toEqual(2)
3649 expect(f3.length).toEqual(3)
3650})
3651
3652test('passes context to its functions', () => {
3653 const a = function (x){
3654 return this.f1(x)
3655 }
3656 const b = function (x){
3657 return this.f2(x)
3658 }
3659 const c = function (x, y){
3660 return this.f3(x, y)
3661 }
3662 const d = converge(c, [ a, b ])
3663 const context = {
3664 f1 : add(1),
3665 f2 : add(2),
3666 f3 : add,
3667 }
3668 expect(a.call(context, 1)).toEqual(2)
3669 expect(b.call(context, 1)).toEqual(3)
3670 expect(d.call(context, 1)).toEqual(5)
3671})
3672
3673test('works with empty functions list', () => {
3674 const fn = converge(function (){
3675 return arguments.length
3676 }, [])
3677 expect(fn.length).toEqual(0)
3678 expect(fn()).toEqual(0)
3679})
3680```
3681
3682</details>
3683
3684<details>
3685
3686<summary><strong>Typescript</strong> test</summary>
3687
3688```typescript
3689import {converge} from 'ramda'
3690
3691const mult = (a: number, b: number) => {
3692 return a * b
3693}
3694const fn = converge(mult, [
3695 (a: number) => {
3696 return a
3697 },
3698 (a: number, b: number) => {
3699 return b
3700 },
3701])
3702
3703describe('R.converge', () => {
3704 it('happy', () => {
3705 const result = fn(2, 3)
3706 const curriedResult = fn(2)(3)
3707
3708 result // $ExpectType any
3709 curriedResult // $ExpectType any
3710 })
3711})
3712```
3713
3714</details>
3715
3716[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#converge)
3717
3718### curry
3719
3720```typescript
3721
3722curry(fn: (...args: any[]) => any): (...a: any[]) => any
3723```
3724
3725It expects a function as input and returns its curried version.
3726
3727```javascript
3728const fn = (a, b, c) => a + b + c
3729const curried = R.curry(fn)
3730const sum = curried(1,2)
3731
3732const result = sum(3) // => 6
3733```
3734
3735<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20(a%2C%20b%2C%20c)%20%3D%3E%20a%20%2B%20b%20%2B%20c%0Aconst%20curried%20%3D%20R.curry(fn)%0Aconst%20sum%20%3D%20curried(1%2C2)%0A%0Aconst%20result%20%3D%20sum(3)%20%2F%2F%20%3D%3E%206">Try this <strong>R.curry</strong> example in Rambda REPL</a>
3736
3737<details>
3738
3739<summary>All Typescript definitions</summary>
3740
3741```typescript
3742curry(fn: (...args: any[]) => any): (...a: any[]) => any;
3743```
3744
3745</details>
3746
3747<details>
3748
3749<summary><strong>R.curry</strong> source</summary>
3750
3751```javascript
3752export function curry(fn, args = []){
3753 return (..._args) =>
3754 (rest => rest.length >= fn.length ? fn(...rest) : curry(fn, rest))([
3755 ...args,
3756 ..._args,
3757 ])
3758}
3759```
3760
3761</details>
3762
3763<details>
3764
3765<summary><strong>Tests</strong></summary>
3766
3767```javascript
3768import { curry } from './curry'
3769
3770test('happy', () => {
3771 const addFourNumbers = (
3772 a, b, c, d
3773 ) => a + b + c + d
3774 const curriedAddFourNumbers = curry(addFourNumbers)
3775 const f = curriedAddFourNumbers(1, 2)
3776 const g = f(3)
3777
3778 expect(g(4)).toEqual(10)
3779})
3780
3781test('when called with more arguments', () => {
3782 const add = curry((n, n2) => n + n2)
3783
3784 expect(add(
3785 1, 2, 3
3786 )).toEqual(3)
3787})
3788
3789test('when called with zero arguments', () => {
3790 const sub = curry((a, b) => a - b)
3791 const s0 = sub()
3792
3793 expect(s0(5, 2)).toEqual(3)
3794})
3795
3796test('when called via multiple curry stages', () => {
3797 const join = curry((
3798 a, b, c, d
3799 ) => [ a, b, c, d ].join('-'))
3800
3801 const stage1 = join('A')
3802 const stage2 = stage1('B', 'C')
3803
3804 expect(stage2('D')).toEqual('A-B-C-D')
3805})
3806```
3807
3808</details>
3809
3810<details>
3811
3812<summary><strong>Typescript</strong> test</summary>
3813
3814```typescript
3815import {curry} from 'rambda'
3816
3817function source(a: number, b: number, c: number, d: number) {
3818 void d
3819
3820 return a * b * c
3821}
3822
3823describe('R.curry', () => {
3824 it('happy', () => {
3825 const curried = curry(source)
3826
3827 const result1 = curried(1)(2)(3)
3828 const result2 = curried(1, 2)(3)
3829 const result3 = curried(1)(2, 3)
3830 const result4 = curried(1, 2, 3)
3831
3832 result1 // $ExpectType any
3833 result2 // $ExpectType any
3834 result3 // $ExpectType any
3835 result4 // $ExpectType any
3836 })
3837})
3838```
3839
3840</details>
3841
3842<details>
3843
3844<summary>3 failed <italic>Ramda.curry</italic> specs
3845
3846> :boom: Reason for the failure: Ramda library support placeholder(R.__)
3847</summary>
3848
3849```javascript
3850var R = require('../../../../dist/rambda.js');
3851var eq = require('./shared/eq');
3852var jsv = require('jsverify');
3853var funcN = require('./shared/funcN');
3854
3855describe('curry', function() {
3856 it('properly reports the length of the curried function', function() {
3857 var f = R.curry(function(a, b, c, d) {return (a + b * c) / d;});
3858 eq(f.length, 4);
3859 var g = f(12);
3860 eq(g.length, 3);
3861 var h = g(3);
3862 eq(h.length, 2);
3863 eq(g(3, 6).length, 1);
3864 });
3865 it('preserves context', function() {
3866 var ctx = {x: 10};
3867 var f = function(a, b) { return a + b * this.x; };
3868 var g = R.curry(f);
3869 eq(g.call(ctx, 2, 4), 42);
3870 eq(g.call(ctx, 2).call(ctx, 4), 42);
3871 });
3872 it('supports R.__ placeholder', function() {
3873 var f = function(a, b, c) { return [a, b, c]; };
3874 var g = R.curry(f);
3875 var _ = R.__;
3876 eq(g(1)(2)(3), [1, 2, 3]);
3877 eq(g(1)(2, 3), [1, 2, 3]);
3878 eq(g(1, 2)(3), [1, 2, 3]);
3879 eq(g(1, 2, 3), [1, 2, 3]);
3880 eq(g(_, 2, 3)(1), [1, 2, 3]);
3881 eq(g(1, _, 3)(2), [1, 2, 3]);
3882 eq(g(1, 2, _)(3), [1, 2, 3]);
3883 eq(g(1, _, _)(2)(3), [1, 2, 3]);
3884 eq(g(_, 2, _)(1)(3), [1, 2, 3]);
3885 eq(g(_, _, 3)(1)(2), [1, 2, 3]);
3886 eq(g(1, _, _)(2, 3), [1, 2, 3]);
3887 eq(g(_, 2, _)(1, 3), [1, 2, 3]);
3888 eq(g(_, _, 3)(1, 2), [1, 2, 3]);
3889 eq(g(1, _, _)(_, 3)(2), [1, 2, 3]);
3890 eq(g(_, 2, _)(_, 3)(1), [1, 2, 3]);
3891 eq(g(_, _, 3)(_, 2)(1), [1, 2, 3]);
3892 eq(g(_, _, _)(_, _)(_)(1, 2, 3), [1, 2, 3]);
3893 eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [1, 2, 3]);
3894 });
3895 it('supports @@functional/placeholder', function() {
3896 var f = function(a, b, c) { return [a, b, c]; };
3897 var g = R.curry(f);
3898 var _ = {'@@functional/placeholder': true, x: Math.random()};
3899 eq(g(1)(2)(3), [1, 2, 3]);
3900 eq(g(1)(2, 3), [1, 2, 3]);
3901 eq(g(1, 2)(3), [1, 2, 3]);
3902 eq(g(1, 2, 3), [1, 2, 3]);
3903 eq(g(_, 2, 3)(1), [1, 2, 3]);
3904 eq(g(1, _, 3)(2), [1, 2, 3]);
3905 eq(g(1, 2, _)(3), [1, 2, 3]);
3906 eq(g(1, _, _)(2)(3), [1, 2, 3]);
3907 eq(g(_, 2, _)(1)(3), [1, 2, 3]);
3908 eq(g(_, _, 3)(1)(2), [1, 2, 3]);
3909 eq(g(1, _, _)(2, 3), [1, 2, 3]);
3910 eq(g(_, 2, _)(1, 3), [1, 2, 3]);
3911 eq(g(_, _, 3)(1, 2), [1, 2, 3]);
3912 eq(g(1, _, _)(_, 3)(2), [1, 2, 3]);
3913 eq(g(_, 2, _)(_, 3)(1), [1, 2, 3]);
3914 eq(g(_, _, 3)(_, 2)(1), [1, 2, 3]);
3915 eq(g(_, _, _)(_, _)(_)(1, 2, 3), [1, 2, 3]);
3916 eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [1, 2, 3]);
3917 });
3918});
3919describe('curry properties', function() {
3920 jsv.property('curries multiple values', funcN(4), jsv.json, jsv.json, jsv.json, jsv.json, function(f, a, b, c, d) {
3921 var g = R.curry(f);
3922 return R.all(R.equals(f(a, b, c, d)), [
3923 g(a, b, c, d),
3924 g(a)(b)(c)(d),
3925 g(a)(b, c, d),
3926 g(a, b)(c, d),
3927 g(a, b, c)(d)
3928 ]);
3929 jsv.property('curries with placeholder', funcN(3), jsv.json, jsv.json, jsv.json, function(f, a, b, c) {
3930 var _ = {'@@functional/placeholder': true, x: Math.random()};
3931 var g = R.curry(f);
3932 return R.all(R.equals(f(a, b, c)), [
3933 g(_, _, c)(a, b),
3934 g(a, _, c)(b),
3935 g(_, b, c)(a),
3936 g(a, _, _)(_, c)(b),
3937 g(a, b, _)(c)
3938 ]);
3939});
3940```
3941
3942</details>
3943
3944[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#curry)
3945
3946### curryN
3947
3948```typescript
3949
3950curryN(length: number, fn: (...args: readonly any[]) => any): (...a: readonly any[]) => any
3951```
3952
3953It returns a curried equivalent of the provided function, with the specified arity.
3954
3955<details>
3956
3957<summary>All Typescript definitions</summary>
3958
3959```typescript
3960curryN(length: number, fn: (...args: readonly any[]) => any): (...a: readonly any[]) => any;
3961```
3962
3963</details>
3964
3965<details>
3966
3967<summary><strong>R.curryN</strong> source</summary>
3968
3969```javascript
3970function _curryN(
3971 n, cache, fn
3972){
3973 return function (){
3974 let ci = 0
3975 let ai = 0
3976 const cl = cache.length
3977 const al = arguments.length
3978 const args = new Array(cl + al)
3979 while (ci < cl){
3980 args[ ci ] = cache[ ci ]
3981 ci++
3982 }
3983 while (ai < al){
3984 args[ cl + ai ] = arguments[ ai ]
3985 ai++
3986 }
3987 const remaining = n - args.length
3988
3989 return args.length >= n ?
3990 fn.apply(this, args) :
3991 _arity(remaining, _curryN(
3992 n, args, fn
3993 ))
3994 }
3995}
3996
3997function _arity(n, fn){
3998 switch (n){
3999 case 0:
4000 return function (){
4001 return fn.apply(this, arguments)
4002 }
4003 case 1:
4004 return function (_1){
4005 return fn.apply(this, arguments)
4006 }
4007 case 2:
4008 return function (_1, _2){
4009 return fn.apply(this, arguments)
4010 }
4011 case 3:
4012 return function (
4013 _1, _2, _3
4014 ){
4015 return fn.apply(this, arguments)
4016 }
4017 case 4:
4018 return function (
4019 _1, _2, _3, _4
4020 ){
4021 return fn.apply(this, arguments)
4022 }
4023 case 5:
4024 return function (
4025 _1, _2, _3, _4, _5
4026 ){
4027 return fn.apply(this, arguments)
4028 }
4029 case 6:
4030 return function (
4031 _1, _2, _3, _4, _5, _6
4032 ){
4033 return fn.apply(this, arguments)
4034 }
4035 case 7:
4036 return function (
4037 _1, _2, _3, _4, _5, _6, _7
4038 ){
4039 return fn.apply(this, arguments)
4040 }
4041 case 8:
4042 return function (
4043 _1, _2, _3, _4, _5, _6, _7, _8
4044 ){
4045 return fn.apply(this, arguments)
4046 }
4047 case 9:
4048 return function (
4049 _1, _2, _3, _4, _5, _6, _7, _8, _9
4050 ){
4051 return fn.apply(this, arguments)
4052 }
4053 case 10:
4054 return function (
4055 _1, _2, _3, _4, _5, _6, _7, _8, _9, _10
4056 ){
4057 return fn.apply(this, arguments)
4058 }
4059 default:
4060 throw new Error('First argument to _arity must be a non-negative integer no greater than ten')
4061 }
4062}
4063
4064export function curryN(n, fn){
4065 if (arguments.length === 1) return _fn => curryN(n, _fn)
4066
4067 return _arity(n, _curryN(
4068 n, [], fn
4069 ))
4070}
4071```
4072
4073</details>
4074
4075<details>
4076
4077<summary><strong>Tests</strong></summary>
4078
4079```javascript
4080import { curryN } from './curryN'
4081
4082function source(
4083 a, b, c, d
4084){
4085 void d
4086
4087 return a * b * c
4088}
4089
4090test('accepts an arity', () => {
4091 const curried = curryN(3, source)
4092 expect(curried(1)(2)(3)).toEqual(6)
4093 expect(curried(1, 2)(3)).toEqual(6)
4094 expect(curried(1)(2, 3)).toEqual(6)
4095 expect(curried(
4096 1, 2, 3
4097 )).toEqual(6)
4098})
4099
4100test('can be partially applied', () => {
4101 const curry3 = curryN(3)
4102 const curried = curry3(source)
4103 expect(curried.length).toEqual(3)
4104 expect(curried(1)(2)(3)).toEqual(6)
4105 expect(curried(1, 2)(3)).toEqual(6)
4106 expect(curried(1)(2, 3)).toEqual(6)
4107 expect(curried(
4108 1, 2, 3
4109 )).toEqual(6)
4110})
4111
4112test('preserves context', () => {
4113 const ctx = { x : 10 }
4114 const f = function (a, b){
4115 return a + b * this.x
4116 }
4117 const g = curryN(2, f)
4118
4119 expect(g.call(
4120 ctx, 2, 4
4121 )).toEqual(42)
4122 expect(g.call(ctx, 2).call(ctx, 4)).toEqual(42)
4123})
4124
4125test('forwards extra arguments', () => {
4126 const f = function (){
4127 return Array.prototype.slice.call(arguments)
4128 }
4129 const g = curryN(3, f)
4130
4131 expect(g(
4132 1, 2, 3
4133 )).toEqual([ 1, 2, 3 ])
4134 expect(g(
4135 1, 2, 3, 4
4136 )).toEqual([ 1, 2, 3, 4 ])
4137 expect(g(1, 2)(3, 4)).toEqual([ 1, 2, 3, 4 ])
4138 expect(g(1)(
4139 2, 3, 4
4140 )).toEqual([ 1, 2, 3, 4 ])
4141 expect(g(1)(2)(3, 4)).toEqual([ 1, 2, 3, 4 ])
4142})
4143```
4144
4145</details>
4146
4147<details>
4148
4149<summary><strong>Typescript</strong> test</summary>
4150
4151```typescript
4152import {curryN} from 'ramda'
4153
4154function source(a: number, b: number, c: number, d: number) {
4155 void d
4156
4157 return a * b * c
4158}
4159
4160describe('R.curryN', () => {
4161 it('happy', () => {
4162 const curried = curryN(3, source)
4163
4164 const result1 = curried(1)(2)(3)
4165 const result2 = curried(1, 2)(3)
4166 const result3 = curried(1)(2, 3)
4167 const result4 = curried(1, 2, 3)
4168
4169 result1 // $ExpectType any
4170 result2 // $ExpectType any
4171 result3 // $ExpectType any
4172 result4 // $ExpectType any
4173 })
4174})
4175```
4176
4177</details>
4178
4179[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#curryN)
4180
4181### dec
4182
4183```typescript
4184
4185dec(x: number): number
4186```
4187
4188It decrements a number.
4189
4190<details>
4191
4192<summary>All Typescript definitions</summary>
4193
4194```typescript
4195dec(x: number): number;
4196```
4197
4198</details>
4199
4200<details>
4201
4202<summary><strong>R.dec</strong> source</summary>
4203
4204```javascript
4205export const dec = x => x - 1
4206```
4207
4208</details>
4209
4210<details>
4211
4212<summary><strong>Tests</strong></summary>
4213
4214```javascript
4215import { dec } from './dec'
4216
4217test('happy', () => {
4218 expect(dec(2)).toBe(1)
4219})
4220```
4221
4222</details>
4223
4224[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dec)
4225
4226### defaultTo
4227
4228```typescript
4229
4230defaultTo<T>(defaultValue: T): (...inputArguments: (T | null | undefined)[]) => T
4231```
4232
4233It returns `defaultValue`, if all of `inputArguments` are `undefined`, `null` or `NaN`.
4234
4235Else, it returns the first truthy `inputArguments` instance(from left to right).
4236
4237> :boom: Rambda's **defaultTo** accept indefinite number of arguments when non curried, i.e. `R.defaultTo(2, foo, bar, baz)`.
4238
4239```javascript
4240// With single input argument
4241R.defaultTo('foo', 'bar') // => 'bar'
4242R.defaultTo('foo', undefined) // => 'foo'
4243
4244// With multiple input arguments
4245R.defaultTo('foo', undefined, null, NaN) // => 'foo'
4246R.defaultTo('foo', undefined, 'bar', NaN, 'qux') // => 'bar'
4247R.defaultTo('foo', undefined, null, NaN, 'quz') // => 'qux'
4248```
4249
4250<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%2F%2F%20With%20single%20input%20argument%0AR.defaultTo('foo'%2C%20'bar')%20%2F%2F%20%3D%3E%20'bar'%0AR.defaultTo('foo'%2C%20undefined)%20%2F%2F%20%3D%3E%20'foo'%0A%0A%2F%2F%20With%20multiple%20input%20arguments%0AR.defaultTo('foo'%2C%20undefined%2C%20null%2C%20NaN)%20%2F%2F%20%3D%3E%20'foo'%0AR.defaultTo('foo'%2C%20undefined%2C%20'bar'%2C%20NaN%2C%20'qux')%20%2F%2F%20%3D%3E%20'bar'%0AR.defaultTo('foo'%2C%20undefined%2C%20null%2C%20NaN%2C%20'quz')%20%2F%2F%20%3D%3E%20'qux'">Try this <strong>R.defaultTo</strong> example in Rambda REPL</a>
4251
4252<details>
4253
4254<summary>All Typescript definitions</summary>
4255
4256```typescript
4257defaultTo<T>(defaultValue: T): (...inputArguments: (T | null | undefined)[]) => T;
4258defaultTo<T>(defaultValue: T, ...inputArguments: (T | null | undefined)[]): T;
4259defaultTo<T, U>(defaultValue: T | U, ...inputArguments: (T | U | null | undefined)[]): T | U;
4260```
4261
4262</details>
4263
4264<details>
4265
4266<summary><strong>R.defaultTo</strong> source</summary>
4267
4268```javascript
4269function flagIs(inputArguments){
4270 return (
4271 inputArguments === undefined ||
4272 inputArguments === null ||
4273 Number.isNaN(inputArguments) === true
4274 )
4275}
4276
4277export function defaultTo(defaultArgument, ...inputArguments){
4278 if (arguments.length === 1){
4279 return (..._inputArguments) =>
4280 defaultTo(defaultArgument, ..._inputArguments)
4281 }
4282
4283 const limit = inputArguments.length - 1
4284 let len = limit + 1
4285 let ready = false
4286 let holder
4287
4288 while (!ready){
4289 const instance = inputArguments[ limit - len + 1 ]
4290
4291 if (len === 0){
4292 ready = true
4293 } else if (flagIs(instance)){
4294 len -= 1
4295 } else {
4296 holder = instance
4297 ready = true
4298 }
4299 }
4300
4301 return holder === undefined ? defaultArgument : holder
4302}
4303```
4304
4305</details>
4306
4307<details>
4308
4309<summary><strong>Tests</strong></summary>
4310
4311```javascript
4312import { defaultTo } from './defaultTo'
4313
4314test('with undefined', () => {
4315 expect(defaultTo('foo')(undefined)).toEqual('foo')
4316})
4317
4318test('with null', () => {
4319 expect(defaultTo('foo')(null)).toEqual('foo')
4320})
4321
4322test('with NaN', () => {
4323 expect(defaultTo('foo')(NaN)).toEqual('foo')
4324})
4325
4326test('with empty string', () => {
4327 expect(defaultTo('foo', '')).toEqual('')
4328})
4329
4330test('with false', () => {
4331 expect(defaultTo('foo', false)).toEqual(false)
4332})
4333
4334test('when inputArgument passes initial check', () => {
4335 expect(defaultTo('foo', 'bar')).toEqual('bar')
4336})
4337
4338test('default extends to indefinite input arguments - case 1', () => {
4339 const result = defaultTo(
4340 'foo', null, 'bar'
4341 )
4342 const expected = 'bar'
4343
4344 expect(result).toEqual(expected)
4345})
4346
4347test('default extends to indefinite input arguments - case 2', () => {
4348 const result = defaultTo(
4349 'foo', null, NaN, 'bar'
4350 )
4351 const expected = 'bar'
4352
4353 expect(result).toEqual(expected)
4354})
4355
4356test('default extends to indefinite input arguments - case 3', () => {
4357 const result = defaultTo(
4358 'foo', null, NaN, undefined
4359 )
4360 const expected = 'foo'
4361
4362 expect(result).toEqual(expected)
4363})
4364
4365test('default extends to indefinite input arguments - case 4', () => {
4366 const result = defaultTo(
4367 'foo', null, NaN, undefined, 'bar'
4368 )
4369 const expected = 'bar'
4370
4371 expect(result).toEqual(expected)
4372})
4373
4374test('default extends to indefinite input arguments - case 5', () => {
4375 const result = defaultTo(
4376 'foo', null, NaN, 'bar', 'baz'
4377 )
4378 const expected = 'bar'
4379
4380 expect(result).toEqual(expected)
4381})
4382
4383test('default extends to indefinite input arguments - case 6', () => {
4384 const result = defaultTo(
4385 'foo', null, NaN, undefined, null, NaN
4386 )
4387 const expected = 'foo'
4388
4389 expect(result).toEqual(expected)
4390})
4391```
4392
4393</details>
4394
4395<details>
4396
4397<summary><strong>Typescript</strong> test</summary>
4398
4399```typescript
4400import {defaultTo} from 'rambda'
4401
4402describe('R.defaultTo with Ramda spec', () => {
4403 it('input is falsy', () => {
4404 const result = defaultTo('foo', undefined)
4405 result // $ExpectType "foo"
4406 })
4407 it('input is truthy', () => {
4408 const result = defaultTo('foo', 'bar')
4409 result // $ExpectType "foo" | "bar"
4410 })
4411})
4412
4413describe('R.defaultTo can have many inputs', () => {
4414 it('happy', () => {
4415 const result = defaultTo('foo', undefined, 'bar')
4416 result // $ExpectType "foo" | "bar"
4417 })
4418
4419 it('curried', () => {
4420 const result = defaultTo('foo')(undefined, 'bar')
4421 result // $ExpectType string
4422 })
4423
4424 it('with two possible types', () => {
4425 const result = defaultTo<string, number>(
4426 'foo',
4427 undefined,
4428 1,
4429 null,
4430 2,
4431 'bar'
4432 )
4433 result // $ExpectType string | number
4434 })
4435})
4436```
4437
4438</details>
4439
4440[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#defaultTo)
4441
4442### difference
4443
4444```typescript
4445
4446difference<T>(a: readonly T[], b: readonly T[]): T[]
4447```
4448
4449It returns the uniq set of all elements in the first list `a` not contained in the second list `b`.
4450
4451```javascript
4452const a = [ 1, 2, 3, 4 ]
4453const b = [ 3, 4, 5, 6 ]
4454
4455const result = difference(a, b)
4456// => [ 1, 2 ]
4457```
4458
4459<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20a%20%3D%20%5B%201%2C%202%2C%203%2C%204%20%5D%0Aconst%20b%20%3D%20%5B%203%2C%204%2C%205%2C%206%20%5D%0A%0Aconst%20result%20%3D%20difference(a%2C%20b)%0A%2F%2F%20%3D%3E%20%5B%201%2C%202%20%5D">Try this <strong>R.difference</strong> example in Rambda REPL</a>
4460
4461<details>
4462
4463<summary>All Typescript definitions</summary>
4464
4465```typescript
4466difference<T>(a: readonly T[], b: readonly T[]): T[];
4467difference<T>(a: readonly T[]): (b: readonly T[]) => T[];
4468```
4469
4470</details>
4471
4472<details>
4473
4474<summary><strong>R.difference</strong> source</summary>
4475
4476```javascript
4477import { includes } from './includes'
4478import { uniq } from './uniq'
4479
4480export function difference(a, b){
4481 if (arguments.length === 1) return _b => difference(a, _b)
4482
4483 return uniq(a).filter(aInstance => !includes(aInstance, b))
4484}
4485```
4486
4487</details>
4488
4489<details>
4490
4491<summary><strong>Tests</strong></summary>
4492
4493```javascript
4494import { difference } from './difference'
4495
4496test('difference', () => {
4497 const a = [ 1, 2, 3, 4 ]
4498 const b = [ 3, 4, 5, 6 ]
4499 expect(difference(a)(b)).toEqual([ 1, 2 ])
4500
4501 expect(difference([], [])).toEqual([])
4502})
4503
4504test('difference with objects', () => {
4505 const a = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
4506 const b = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
4507 expect(difference(a, b)).toEqual([ { id : 1 }, { id : 2 } ])
4508})
4509
4510test('no duplicates in first list', () => {
4511 const M2 = [ 1, 2, 3, 4, 1, 2, 3, 4 ]
4512 const N2 = [ 3, 3, 4, 4, 5, 5, 6, 6 ]
4513 expect(difference(M2, N2)).toEqual([ 1, 2 ])
4514})
4515
4516test('should use R.equals', () => {
4517 expect(difference([ NaN ], [ NaN ]).length).toEqual(0)
4518})
4519```
4520
4521</details>
4522
4523<details>
4524
4525<summary><strong>Typescript</strong> test</summary>
4526
4527```typescript
4528import {difference} from 'rambda'
4529
4530const list1 = [1, 2, 3]
4531const list2 = [1, 2, 4]
4532
4533describe('R.difference', () => {
4534 it('happy', () => {
4535 const result = difference(list1, list2)
4536
4537 result // $ExpectType number[]
4538 })
4539 it('curried', () => {
4540 const result = difference(list1)(list2)
4541
4542 result // $ExpectType number[]
4543 })
4544})
4545```
4546
4547</details>
4548
4549[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#difference)
4550
4551### dissoc
4552
4553```typescript
4554
4555dissoc<T>(prop: string, obj: any): T
4556```
4557
4558It returns a new object that does not contain property `prop`.
4559
4560```javascript
4561R.dissoc('b', {a: 1, b: 2, c: 3})
4562//=> {a: 1, c: 3}
4563```
4564
4565<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.dissoc('b'%2C%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D)%0A%2F%2F%3D%3E%20%7Ba%3A%201%2C%20c%3A%203%7D">Try this <strong>R.dissoc</strong> example in Rambda REPL</a>
4566
4567<details>
4568
4569<summary>All Typescript definitions</summary>
4570
4571```typescript
4572dissoc<T>(prop: string, obj: any): T;
4573dissoc<T>(prop: string): (obj: any) => T;
4574```
4575
4576</details>
4577
4578<details>
4579
4580<summary><strong>R.dissoc</strong> source</summary>
4581
4582```javascript
4583export function dissoc(prop, obj){
4584 if (arguments.length === 1) return _obj => dissoc(prop, _obj)
4585
4586 if (obj === null || obj === undefined) return {}
4587
4588 const willReturn = {}
4589 for (const p in obj){
4590 willReturn[ p ] = obj[ p ]
4591 }
4592 delete willReturn[ prop ]
4593
4594 return willReturn
4595}
4596```
4597
4598</details>
4599
4600<details>
4601
4602<summary><strong>Tests</strong></summary>
4603
4604```javascript
4605import { dissoc } from './dissoc'
4606
4607test('input is null or undefined', () => {
4608 expect(dissoc('b', null)).toEqual({})
4609 expect(dissoc('b', undefined)).toEqual({})
4610})
4611
4612test('property exists curried', () => {
4613 expect(dissoc('b')({
4614 a : 1,
4615 b : 2,
4616 })).toEqual({ a : 1 })
4617})
4618
4619test('property doesn\'t exists', () => {
4620 expect(dissoc('c', {
4621 a : 1,
4622 b : 2,
4623 })).toEqual({
4624 a : 1,
4625 b : 2,
4626 })
4627})
4628
4629test('works with non-string property', () => {
4630 expect(dissoc(42, {
4631 a : 1,
4632 42 : 2,
4633 })).toEqual({ a : 1 })
4634
4635 expect(dissoc(null, {
4636 a : 1,
4637 null : 2,
4638 })).toEqual({ a : 1 })
4639
4640 expect(dissoc(undefined, {
4641 a : 1,
4642 undefined : 2,
4643 })).toEqual({ a : 1 })
4644})
4645
4646test('includes prototype properties', () => {
4647 function Rectangle(width, height){
4648 this.width = width
4649 this.height = height
4650 }
4651 const area = Rectangle.prototype.area = function (){
4652 return this.width * this.height
4653 }
4654 const rect = new Rectangle(7, 6)
4655
4656 expect(dissoc('area', rect)).toEqual({
4657 width : 7,
4658 height : 6,
4659 })
4660
4661 expect(dissoc('width', rect)).toEqual({
4662 height : 6,
4663 area : area,
4664 })
4665
4666 expect(dissoc('depth', rect)).toEqual({
4667 width : 7,
4668 height : 6,
4669 area : area,
4670 })
4671})
4672```
4673
4674</details>
4675
4676<details>
4677
4678<summary><strong>Typescript</strong> test</summary>
4679
4680```typescript
4681import {dissoc, pipe, identity} from 'rambda'
4682
4683const obj = {
4684 a: 1,
4685 b: 2,
4686}
4687interface Output {
4688 a: string,
4689}
4690
4691describe('R.dissoc', () => {
4692 it('happy', () => {
4693 const result = dissoc<Output>('b', obj)
4694
4695 result // $ExpectType Output
4696 })
4697 it('curried', () => {
4698 const result = dissoc<Output>('b')(obj)
4699
4700 result // $ExpectType Output
4701 })
4702 it('within R.pipe', () => {
4703 const result = pipe<object, object, Output>(identity, dissoc('b'))(obj)
4704
4705 result // $ExpectType Output
4706 })
4707})
4708```
4709
4710</details>
4711
4712[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dissoc)
4713
4714### divide
4715
4716```typescript
4717
4718divide(x: number, y: number): number
4719```
4720
4721```javascript
4722R.divide(71, 100) // => 0.71
4723```
4724
4725<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.divide(71%2C%20100)%20%2F%2F%20%3D%3E%200.71">Try this <strong>R.divide</strong> example in Rambda REPL</a>
4726
4727<details>
4728
4729<summary>All Typescript definitions</summary>
4730
4731```typescript
4732divide(x: number, y: number): number;
4733divide(x: number): (y: number) => number;
4734```
4735
4736</details>
4737
4738<details>
4739
4740<summary><strong>R.divide</strong> source</summary>
4741
4742```javascript
4743export function divide(a, b){
4744 if (arguments.length === 1) return _b => divide(a, _b)
4745
4746 return a / b
4747}
4748```
4749
4750</details>
4751
4752<details>
4753
4754<summary><strong>Tests</strong></summary>
4755
4756```javascript
4757import { divide } from './divide'
4758
4759test('happy', () => {
4760 expect(divide(71, 100)).toEqual(0.71)
4761 expect(divide(71)(100)).toEqual(0.71)
4762})
4763```
4764
4765</details>
4766
4767[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#divide)
4768
4769### drop
4770
4771```typescript
4772
4773drop<T>(howMany: number, input: readonly T[]): T[]
4774```
4775
4776It returns `howMany` items dropped from beginning of list or string `input`.
4777
4778```javascript
4779R.drop(2, ['foo', 'bar', 'baz']) // => ['baz']
4780R.drop(2, 'foobar') // => 'obar'
4781```
4782
4783<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.drop(2%2C%20%5B'foo'%2C%20'bar'%2C%20'baz'%5D)%20%2F%2F%20%3D%3E%20%5B'baz'%5D%0AR.drop(2%2C%20'foobar')%20%20%2F%2F%20%3D%3E%20'obar'">Try this <strong>R.drop</strong> example in Rambda REPL</a>
4784
4785<details>
4786
4787<summary>All Typescript definitions</summary>
4788
4789```typescript
4790drop<T>(howMany: number, input: readonly T[]): T[];
4791drop(howMany: number, input: string): string;
4792drop<T>(howMany: number): {
4793 <T>(input: readonly T[]): T[];
4794 (input: string): string;
4795};
4796```
4797
4798</details>
4799
4800<details>
4801
4802<summary><strong>R.drop</strong> source</summary>
4803
4804```javascript
4805export function drop(howManyToDrop, listOrString){
4806 if (arguments.length === 1) return _list => drop(howManyToDrop, _list)
4807
4808 return listOrString.slice(howManyToDrop > 0 ? howManyToDrop : 0)
4809}
4810```
4811
4812</details>
4813
4814<details>
4815
4816<summary><strong>Tests</strong></summary>
4817
4818```javascript
4819import assert from 'assert'
4820
4821import { drop } from './drop'
4822
4823test('with array', () => {
4824 expect(drop(2)([ 'foo', 'bar', 'baz' ])).toEqual([ 'baz' ])
4825 expect(drop(3, [ 'foo', 'bar', 'baz' ])).toEqual([])
4826 expect(drop(4, [ 'foo', 'bar', 'baz' ])).toEqual([])
4827})
4828
4829test('with string', () => {
4830 expect(drop(3, 'rambda')).toEqual('bda')
4831})
4832
4833test('with non-positive count', () => {
4834 expect(drop(0, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4835 expect(drop(-1, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4836 expect(drop(-Infinity, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4837})
4838
4839test('should return copy', () => {
4840 const xs = [ 1, 2, 3 ]
4841
4842 assert.notStrictEqual(drop(0, xs), xs)
4843 assert.notStrictEqual(drop(-1, xs), xs)
4844})
4845```
4846
4847</details>
4848
4849<details>
4850
4851<summary><strong>Typescript</strong> test</summary>
4852
4853```typescript
4854import {drop} from 'rambda'
4855
4856const list = [1, 2, 3, 4]
4857const str = 'foobar'
4858const howMany = 2
4859
4860describe('R.drop - array', () => {
4861 it('happy', () => {
4862 const result = drop(howMany, list)
4863 result // $ExpectType number[]
4864 })
4865 it('curried', () => {
4866 const result = drop(howMany)(list)
4867 result // $ExpectType number[]
4868 })
4869})
4870
4871describe('R.drop - string', () => {
4872 it('happy', () => {
4873 const result = drop(howMany, str)
4874 result // $ExpectType string
4875 })
4876 it('curried', () => {
4877 const result = drop(howMany)(str)
4878 result // $ExpectType string
4879 })
4880})
4881```
4882
4883</details>
4884
4885[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#drop)
4886
4887### dropLast
4888
4889```typescript
4890
4891dropLast<T>(howMany: number, input: readonly T[]): T[]
4892```
4893
4894It returns `howMany` items dropped from the end of list or string `input`.
4895
4896```javascript
4897R.dropLast(2, ['foo', 'bar', 'baz']) // => ['foo']
4898R.dropLast(2, 'foobar') // => 'foob'
4899```
4900
4901<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.dropLast(2%2C%20%5B'foo'%2C%20'bar'%2C%20'baz'%5D)%20%2F%2F%20%3D%3E%20%5B'foo'%5D%0AR.dropLast(2%2C%20'foobar')%20%20%2F%2F%20%3D%3E%20'foob'">Try this <strong>R.dropLast</strong> example in Rambda REPL</a>
4902
4903<details>
4904
4905<summary>All Typescript definitions</summary>
4906
4907```typescript
4908dropLast<T>(howMany: number, input: readonly T[]): T[];
4909dropLast(howMany: number, input: string): string;
4910dropLast<T>(howMany: number): {
4911 <T>(input: readonly T[]): T[];
4912 (input: string): string;
4913};
4914```
4915
4916</details>
4917
4918<details>
4919
4920<summary><strong>R.dropLast</strong> source</summary>
4921
4922```javascript
4923export function dropLast(howManyToDrop, listOrString){
4924 if (arguments.length === 1){
4925 return _listOrString => dropLast(howManyToDrop, _listOrString)
4926 }
4927
4928 return howManyToDrop > 0 ?
4929 listOrString.slice(0, -howManyToDrop) :
4930 listOrString.slice()
4931}
4932```
4933
4934</details>
4935
4936<details>
4937
4938<summary><strong>Tests</strong></summary>
4939
4940```javascript
4941import assert from 'assert'
4942
4943import { dropLast } from './dropLast'
4944
4945test('with array', () => {
4946 expect(dropLast(2)([ 'foo', 'bar', 'baz' ])).toEqual([ 'foo' ])
4947 expect(dropLast(3, [ 'foo', 'bar', 'baz' ])).toEqual([])
4948 expect(dropLast(4, [ 'foo', 'bar', 'baz' ])).toEqual([])
4949})
4950
4951test('with string', () => {
4952 expect(dropLast(3, 'rambda')).toEqual('ram')
4953})
4954
4955test('with non-positive count', () => {
4956 expect(dropLast(0, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4957 expect(dropLast(-1, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4958 expect(dropLast(-Infinity, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
4959})
4960
4961test('should return copy', () => {
4962 const xs = [ 1, 2, 3 ]
4963
4964 assert.notStrictEqual(dropLast(0, xs), xs)
4965 assert.notStrictEqual(dropLast(-1, xs), xs)
4966})
4967```
4968
4969</details>
4970
4971<details>
4972
4973<summary><strong>Typescript</strong> test</summary>
4974
4975```typescript
4976import {dropLast} from 'rambda'
4977
4978const list = [1, 2, 3, 4]
4979const str = 'foobar'
4980const howMany = 2
4981
4982describe('R.dropLast - array', () => {
4983 it('happy', () => {
4984 const result = dropLast(howMany, list)
4985 result // $ExpectType number[]
4986 })
4987 it('curried', () => {
4988 const result = dropLast(howMany)(list)
4989 result // $ExpectType number[]
4990 })
4991})
4992
4993describe('R.dropLast - string', () => {
4994 it('happy', () => {
4995 const result = dropLast(howMany, str)
4996 result // $ExpectType string
4997 })
4998 it('curried', () => {
4999 const result = dropLast(howMany)(str)
5000 result // $ExpectType string
5001 })
5002})
5003```
5004
5005</details>
5006
5007<details>
5008
5009<summary>5 failed <italic>Ramda.dropLast</italic> specs
5010
5011> :boom: Reason for the failure: Ramda method can act as a transducer
5012</summary>
5013
5014```javascript
5015var assert = require('assert');
5016
5017var R = require('../../../../dist/rambda.js');
5018var eq = require('./shared/eq');
5019describe('dropLast', function() {
5020 it('can act as a transducer', function() {
5021 var dropLast2 = R.dropLast(2);
5022 assert.deepEqual(R.into([], dropLast2, [1, 3, 5, 7, 9, 1, 2]), [1, 3, 5, 7, 9]);
5023 assert.deepEqual(R.into([], dropLast2, [1]), []);
5024 });
5025});
5026```
5027
5028</details>
5029
5030[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dropLast)
5031
5032### dropLastWhile
5033
5034```typescript
5035
5036dropLastWhile(predicate: (x: string) => boolean, iterable: string): string
5037```
5038
5039```javascript
5040const list = [1, 2, 3, 4, 5];
5041const predicate = x => x >= 3
5042
5043const result = dropLastWhile(predicate, list);
5044// => [1, 2]
5045```
5046
5047<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%2C%205%5D%3B%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%3D%203%0A%0Aconst%20result%20%3D%20dropLastWhile(predicate%2C%20list)%3B%0A%2F%2F%20%3D%3E%20%5B1%2C%202%5D">Try this <strong>R.dropLastWhile</strong> example in Rambda REPL</a>
5048
5049<details>
5050
5051<summary>All Typescript definitions</summary>
5052
5053```typescript
5054dropLastWhile(predicate: (x: string) => boolean, iterable: string): string;
5055dropLastWhile(predicate: (x: string) => boolean): (iterable: string) => string;
5056dropLastWhile<T>(predicate: (x: T) => boolean, iterable: readonly T[]): T[];
5057dropLastWhile<T>(predicate: (x: T) => boolean): <T>(iterable: readonly T[]) => T[];
5058```
5059
5060</details>
5061
5062<details>
5063
5064<summary><strong>R.dropLastWhile</strong> source</summary>
5065
5066```javascript
5067import { _isArray } from './_internals/_isArray.js'
5068
5069export function dropLastWhile(predicate, iterable){
5070 if (arguments.length === 1){
5071 return _iterable => dropLastWhile(predicate, _iterable)
5072 }
5073 if (iterable.length === 0) return iterable
5074 const isArray = _isArray(iterable)
5075
5076 if (typeof predicate !== 'function'){
5077 throw new Error(`'predicate' is from wrong type ${ typeof predicate }`)
5078 }
5079 if (!isArray && typeof iterable !== 'string'){
5080 throw new Error(`'iterable' is from wrong type ${ typeof iterable }`)
5081 }
5082
5083 let found = false
5084 const toReturn = []
5085 let counter = iterable.length
5086
5087 while (counter > 0){
5088 counter--
5089 if (!found && predicate(iterable[ counter ]) === false){
5090 found = true
5091 toReturn.push(iterable[ counter ])
5092 } else if (found){
5093 toReturn.push(iterable[ counter ])
5094 }
5095 }
5096
5097 return isArray ? toReturn.reverse() : toReturn.reverse().join('')
5098}
5099```
5100
5101</details>
5102
5103<details>
5104
5105<summary><strong>Tests</strong></summary>
5106
5107```javascript
5108import { dropLastWhile as dropLastWhileRamda } from "ramda";
5109
5110import { compareCombinations } from "./_internals/testUtils";
5111import { dropLastWhile } from "./dropLastWhile";
5112
5113const list = [1, 2, 3, 4, 5];
5114const str = "foobar";
5115
5116test("with list", () => {
5117 const result = dropLastWhile((x) => x >= 3, list);
5118 expect(result).toEqual([1, 2]);
5119});
5120
5121test("with string", () => {
5122 const result = dropLastWhile((x) => x !== "b")(str);
5123 expect(result).toBe("foob");
5124});
5125
5126test("with empty list", () => {
5127 expect(dropLastWhile(() => true, [])).toEqual([]);
5128 expect(dropLastWhile(() => false, [])).toEqual([]);
5129});
5130
5131const possiblePredicates = [
5132 (x) => x > 2,
5133 (x) => x < 2,
5134 (x) => x < -2,
5135 (x) => x > 10,
5136 "",
5137 [],
5138 [1],
5139];
5140
5141const possibleIterables = [
5142 list,
5143 [{}, "1", 2],
5144 str,
5145 `${str}${str}`,
5146 /foo/g,
5147 Promise.resolve("foo"),
5148 2,
5149];
5150
5151describe("brute force", () => {
5152 compareCombinations({
5153 fn: dropLastWhile,
5154 fnRamda: dropLastWhileRamda,
5155 firstInput: possiblePredicates,
5156 secondInput: possibleIterables,
5157 callback: (errorsCounters) => {
5158 expect(errorsCounters).toMatchInlineSnapshot(`
5159 Object {
5160 "ERRORS_MESSAGE_MISMATCH": 0,
5161 "ERRORS_TYPE_MISMATCH": 12,
5162 "RESULTS_MISMATCH": 0,
5163 "SHOULD_NOT_THROW": 21,
5164 "SHOULD_THROW": 0,
5165 }
5166 `);
5167 },
5168 });
5169});
5170```
5171
5172</details>
5173
5174<details>
5175
5176<summary><strong>Typescript</strong> test</summary>
5177
5178```typescript
5179import {dropLastWhile} from 'rambda'
5180
5181const list = [1, 2, 3]
5182const str = 'FOO'
5183
5184describe('R.dropLastWhile', () => {
5185 it('with array', () => {
5186 const result = dropLastWhile(x => x > 1, list)
5187
5188 result // $ExpectType number[]
5189 })
5190 it('with array - curried', () => {
5191 const result = dropLastWhile(x => x > 1, list)
5192
5193 result // $ExpectType number[]
5194 })
5195 it('with string', () => {
5196 const result = dropLastWhile(x => x !== 'F', str)
5197
5198 result // $ExpectType string
5199 })
5200 it('with string - curried', () => {
5201 const result = dropLastWhile(x => x !== 'F')(str)
5202
5203 result // $ExpectType string
5204 })
5205})
5206```
5207
5208</details>
5209
5210*1 failed Ramda.dropLastWhile specs*
5211
5212> :boom: Reason for the failure: Ramda method can act as a transducer
5213
5214[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dropLastWhile)
5215
5216### dropRepeats
5217
5218```typescript
5219
5220dropRepeats<T>(list: readonly T[]): T[]
5221```
5222
5223It removes any successive duplicates according to `R.equals`.
5224
5225```javascript
5226const result = R.dropRepeats([
5227 1,
5228 1,
5229 {a: 1},
5230 {a:1},
5231 1
5232])
5233// => [1, {a: 1}, 1]
5234```
5235
5236<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.dropRepeats(%5B%0A%20%201%2C%20%0A%20%201%2C%20%0A%20%20%7Ba%3A%201%7D%2C%20%0A%20%20%7Ba%3A1%7D%2C%20%0A%20%201%0A%5D)%0A%2F%2F%20%3D%3E%20%5B1%2C%20%7Ba%3A%201%7D%2C%201%5D">Try this <strong>R.dropRepeats</strong> example in Rambda REPL</a>
5237
5238<details>
5239
5240<summary>All Typescript definitions</summary>
5241
5242```typescript
5243dropRepeats<T>(list: readonly T[]): T[];
5244```
5245
5246</details>
5247
5248<details>
5249
5250<summary><strong>R.dropRepeats</strong> source</summary>
5251
5252```javascript
5253import { _isArray } from './_internals/_isArray'
5254import { equals } from './equals'
5255
5256export function dropRepeats(list){
5257 if (!_isArray(list)){
5258 throw new Error(`${ list } is not a list`)
5259 }
5260
5261 const toReturn = []
5262
5263 list.reduce((prev, current) => {
5264 if (!equals(prev, current)){
5265 toReturn.push(current)
5266 }
5267
5268 return current
5269 }, undefined)
5270
5271 return toReturn
5272}
5273```
5274
5275</details>
5276
5277<details>
5278
5279<summary><strong>Tests</strong></summary>
5280
5281```javascript
5282import { dropRepeats as dropRepeatsRamda } from "ramda";
5283
5284import { compareCombinations } from "./_internals/testUtils";
5285import { add } from "./add";
5286import { dropRepeats } from "./dropRepeats";
5287
5288const list = [1, 2, 2, 2, 3, 4, 4, 5, 5, 3, 2, 2, { a: 1 }, { a: 1 }];
5289const listClean = [1, 2, 3, 4, 5, 3, 2, { a: 1 }];
5290
5291test("happy", () => {
5292 const result = dropRepeats(list);
5293 expect(result).toEqual(listClean);
5294});
5295
5296const possibleLists = [
5297 [add(1), async () => {}, [1], [1], [2], [2]],
5298 [add(1), add(1), add(2)],
5299 [],
5300 1,
5301 /foo/g,
5302 Promise.resolve(1),
5303];
5304
5305describe("brute force", () => {
5306 compareCombinations({
5307 firstInput: possibleLists,
5308 callback: (errorsCounters) => {
5309 expect(errorsCounters).toMatchInlineSnapshot(`
5310 Object {
5311 "ERRORS_MESSAGE_MISMATCH": 0,
5312 "ERRORS_TYPE_MISMATCH": 0,
5313 "RESULTS_MISMATCH": 0,
5314 "SHOULD_NOT_THROW": 3,
5315 "SHOULD_THROW": 0,
5316 }
5317 `);
5318 },
5319 fn: dropRepeats,
5320 fnRamda: dropRepeatsRamda,
5321 });
5322});
5323```
5324
5325</details>
5326
5327<details>
5328
5329<summary><strong>Typescript</strong> test</summary>
5330
5331```typescript
5332import {dropRepeats} from 'rambda'
5333
5334describe('R.dropRepeats', () => {
5335 it('happy', () => {
5336 const result = dropRepeats([1, 2, 2, 3])
5337
5338 result // $ExpectType number[]
5339 })
5340})
5341```
5342
5343</details>
5344
5345*1 failed Ramda.dropRepeats specs*
5346
5347> :boom: Reason for the failure: Ramda method can act as a transducer
5348
5349[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dropRepeats)
5350
5351### dropRepeatsWith
5352
5353```typescript
5354
5355dropRepeatsWith<T>(predicate: (x: T, y: T) => boolean, list: readonly T[]): T[]
5356```
5357
5358```javascript
5359const list = [{a:1,b:2}, {a:1,b:3}, {a:2, b:4}]
5360const result = R.dropRepeatsWith(R.prop('a'))
5361
5362// => [{a:1,b:2}, {a:2, b:4}]
5363```
5364
5365<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%7Ba%3A1%2Cb%3A2%7D%2C%20%7Ba%3A1%2Cb%3A3%7D%2C%20%7Ba%3A2%2C%20b%3A4%7D%5D%0Aconst%20result%20%3D%20R.dropRepeatsWith(R.prop('a'))%0A%0A%2F%2F%20%3D%3E%20%5B%7Ba%3A1%2Cb%3A2%7D%2C%20%7Ba%3A2%2C%20b%3A4%7D%5D">Try this <strong>R.dropRepeatsWith</strong> example in Rambda REPL</a>
5366
5367<details>
5368
5369<summary>All Typescript definitions</summary>
5370
5371```typescript
5372dropRepeatsWith<T>(predicate: (x: T, y: T) => boolean, list: readonly T[]): T[];
5373dropRepeatsWith<T>(predicate: (x: T, y: T) => boolean): (list: readonly T[]) => T[];
5374```
5375
5376</details>
5377
5378<details>
5379
5380<summary><strong>R.dropRepeatsWith</strong> source</summary>
5381
5382```javascript
5383import { _isArray } from './_internals/_isArray'
5384
5385export function dropRepeatsWith(predicate, list){
5386 if (arguments.length === 1){
5387 return _iterable => dropRepeatsWith(predicate, _iterable)
5388 }
5389
5390 if (!_isArray(list)){
5391 throw new Error(`${ list } is not a list`)
5392 }
5393
5394 const toReturn = []
5395
5396 list.reduce((prev, current) => {
5397 if (prev === undefined){
5398 toReturn.push(current)
5399
5400 return current
5401 }
5402 if (!predicate(prev, current)){
5403 toReturn.push(current)
5404 }
5405
5406 return current
5407 }, undefined)
5408
5409 return toReturn
5410}
5411```
5412
5413</details>
5414
5415<details>
5416
5417<summary><strong>Tests</strong></summary>
5418
5419```javascript
5420import { dropRepeatsWith as dropRepeatsWithRamda, eqProps } from "ramda";
5421
5422import { compareCombinations } from "./_internals/testUtils";
5423import { dropRepeatsWith } from "./dropRepeatsWith";
5424import { path } from "./path";
5425
5426const eqI = eqProps("i");
5427
5428test("happy", () => {
5429 const list = [{ i: 1 }, { i: 2 }, { i: 2 }, { i: 3 }];
5430 const expected = [{ i: 1 }, { i: 2 }, { i: 3 }];
5431 const result = dropRepeatsWith(eqI, list);
5432 expect(result).toEqual(expected);
5433});
5434
5435test("keeps elements from the left predicate input", () => {
5436 const list = [
5437 {
5438 i: 1,
5439 n: 1,
5440 },
5441 {
5442 i: 1,
5443 n: 2,
5444 },
5445 {
5446 i: 1,
5447 n: 3,
5448 },
5449 {
5450 i: 4,
5451 n: 1,
5452 },
5453 {
5454 i: 4,
5455 n: 2,
5456 },
5457 ];
5458 const expected = [
5459 {
5460 i: 1,
5461 n: 1,
5462 },
5463 {
5464 i: 4,
5465 n: 1,
5466 },
5467 ];
5468 const result = dropRepeatsWith(eqI, list);
5469 expect(result).toEqual(expected);
5470});
5471
5472const possiblePredicates = [
5473 null,
5474 undefined,
5475 (x) => x + 1,
5476 (x) => true,
5477 (x) => false,
5478 (x) => "",
5479 path(["a", "b"]),
5480];
5481const possibleLists = [
5482 null,
5483 undefined,
5484 [],
5485 [1],
5486 [{ a: { b: 1 } }, { a: { b: 1 } }],
5487 [/foo/g, /foo/g],
5488];
5489
5490describe("brute force", () => {
5491 compareCombinations({
5492 firstInput: possiblePredicates,
5493 secondInput: possibleLists,
5494 callback: (errorsCounters) => {
5495 expect(errorsCounters).toMatchInlineSnapshot(`
5496 Object {
5497 "ERRORS_MESSAGE_MISMATCH": 4,
5498 "ERRORS_TYPE_MISMATCH": 14,
5499 "RESULTS_MISMATCH": 0,
5500 "SHOULD_NOT_THROW": 0,
5501 "SHOULD_THROW": 0,
5502 }
5503 `);
5504 },
5505 fn: dropRepeatsWith,
5506 fnRamda: dropRepeatsWithRamda,
5507 });
5508});
5509```
5510
5511</details>
5512
5513<details>
5514
5515<summary><strong>Typescript</strong> test</summary>
5516
5517```typescript
5518import {dropRepeatsWith} from 'rambda'
5519
5520interface Foo {
5521 a: number,
5522}
5523
5524describe('R.dropRepeatsWith', () => {
5525 it('happy', () => {
5526 const result = dropRepeatsWith(
5527 (x: Foo, y: Foo) => {
5528 return x.a > y.a
5529 },
5530 [{a: 2}, {a: 1}]
5531 )
5532
5533 result // $ExpectType { a: number; }[]
5534 result[0].a // $ExpectType number
5535 })
5536 it('curried', () => {
5537 const result = dropRepeatsWith((x: Foo, y: Foo) => {
5538 return x.a > y.a
5539 })([{a: 2}, {a: 1}])
5540
5541 result // $ExpectType Foo[]
5542 })
5543})
5544```
5545
5546</details>
5547
5548[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dropRepeatsWith)
5549
5550### dropWhile
5551
5552```typescript
5553
5554dropWhile(fn: Predicate<string>, iterable: string): string
5555```
5556
5557```javascript
5558const list = [1, 2, 3, 4]
5559const predicate = x => x < 3
5560const result = R.dropWhile(predicate, list)
5561// => [3, 4]
5562```
5563
5564<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3C%203%0Aconst%20result%20%3D%20R.dropWhile(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20%5B3%2C%204%5D">Try this <strong>R.dropWhile</strong> example in Rambda REPL</a>
5565
5566<details>
5567
5568<summary>All Typescript definitions</summary>
5569
5570```typescript
5571dropWhile(fn: Predicate<string>, iterable: string): string;
5572dropWhile(fn: Predicate<string>): (iterable: string) => string;
5573dropWhile<T>(fn: Predicate<T>, iterable: readonly T[]): T[];
5574dropWhile<T>(fn: Predicate<T>): (iterable: readonly T[]) => T[];
5575```
5576
5577</details>
5578
5579<details>
5580
5581<summary><strong>R.dropWhile</strong> source</summary>
5582
5583```javascript
5584import { _isArray } from '../src/_internals/_isArray'
5585
5586export function dropWhile(predicate, iterable){
5587 if (arguments.length === 1){
5588 return _iterable => dropWhile(predicate, _iterable)
5589 }
5590 const isArray = _isArray(iterable)
5591 if (!isArray && typeof iterable !== 'string'){
5592 throw new Error('`iterable` is neither list nor a string')
5593 }
5594 let flag = false
5595 const holder = []
5596 let counter = -1
5597
5598 while (counter++ < iterable.length - 1){
5599 if (flag){
5600 holder.push(iterable[ counter ])
5601 } else if (!predicate(iterable[ counter ])){
5602 if (!flag) flag = true
5603
5604 holder.push(iterable[ counter ])
5605 }
5606 }
5607
5608 return isArray ? holder : holder.join('')
5609}
5610```
5611
5612</details>
5613
5614<details>
5615
5616<summary><strong>Tests</strong></summary>
5617
5618```javascript
5619import { dropWhile as dropWhileRamda } from 'ramda'
5620
5621import { compareCombinations } from './_internals/testUtils'
5622import { dropWhile } from './dropWhile'
5623
5624const list = [ 1, 2, 3, 4 ]
5625
5626test('happy', () => {
5627 const predicate = x => x < 3
5628 const result = dropWhile(predicate, list)
5629 expect(result).toEqual([3,4])
5630})
5631
5632test('always true', () => {
5633 const predicate = () => true
5634 const result = dropWhileRamda(predicate, list)
5635 expect(result).toEqual([])
5636})
5637
5638test('always false', () => {
5639 const predicate = () => 0
5640 const result = dropWhile(predicate, list)
5641 expect(result).toEqual(list)
5642})
5643
5644test('works with string as iterable', () => {
5645 const iterable = 'foobar'
5646 const predicate = x => x !== 'b'
5647 const result = dropWhile(predicate, iterable)
5648 expect(result).toBe('bar')
5649})
5650
5651const possiblePredicates = [
5652 null,
5653 undefined,
5654 () => 0,
5655 () => true,
5656 /foo/g,
5657 {},
5658 [],
5659]
5660
5661const possibleIterables = [
5662 null,
5663 undefined,
5664 [],
5665 {},
5666 1,
5667 '',
5668 'foobar',
5669 [ '' ],
5670 [ 1, 2, 3, 4, 5 ],
5671]
5672
5673describe('brute force', () => {
5674 compareCombinations({
5675 firstInput : possiblePredicates,
5676 callback : errorsCounters => {
5677 expect(errorsCounters).toMatchInlineSnapshot(`
5678 Object {
5679 "ERRORS_MESSAGE_MISMATCH": 15,
5680 "ERRORS_TYPE_MISMATCH": 14,
5681 "RESULTS_MISMATCH": 0,
5682 "SHOULD_NOT_THROW": 14,
5683 "SHOULD_THROW": 0,
5684 }
5685 `)
5686 },
5687 secondInput : possibleIterables,
5688 fn : dropWhile,
5689 fnRamda : dropWhileRamda,
5690 })
5691})
5692```
5693
5694</details>
5695
5696<details>
5697
5698<summary><strong>Typescript</strong> test</summary>
5699
5700```typescript
5701import {dropWhile} from 'rambda'
5702
5703const list = [1, 2, 3, 4]
5704
5705describe('R.dropWhile', () => {
5706 it('happy', () => {
5707 const result = dropWhile(x => x > 2, list)
5708
5709 result // $ExpectType number[]
5710 })
5711 it('curried require explicit type', () => {
5712 const result = dropWhile<number>(x => x > 2)(list)
5713
5714 result // $ExpectType number[]
5715 })
5716})
5717
5718describe('with string as iterable', () => {
5719 const str = 'foobar'
5720 it('happy', () => {
5721 const result = dropWhile(x => x !== 'b', str)
5722
5723 result // $ExpectType string
5724 })
5725 it('curried require explicit type', () => {
5726 const result = dropWhile(x => x !== 'b')(str)
5727
5728 result // $ExpectType string
5729 })
5730})
5731```
5732
5733</details>
5734
5735[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#dropWhile)
5736
5737### either
5738
5739```typescript
5740
5741either(firstPredicate: Pred, secondPredicate: Pred): Pred
5742```
5743
5744It returns a new `predicate` function from `firstPredicate` and `secondPredicate` inputs.
5745
5746This `predicate` function will return `true`, if any of the two input predicates return `true`.
5747
5748```javascript
5749const firstPredicate = x => x > 10
5750const secondPredicate = x => x % 2 === 0
5751const predicate = R.either(firstPredicate, secondPredicate)
5752
5753const result = [
5754 predicate(15),
5755 predicate(8),
5756 predicate(7),
5757]
5758//=> [true, true, false]
5759```
5760
5761<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20firstPredicate%20%3D%20x%20%3D%3E%20x%20%3E%2010%0Aconst%20secondPredicate%20%3D%20x%20%3D%3E%20x%20%25%202%20%3D%3D%3D%200%0Aconst%20predicate%20%3D%20R.either(firstPredicate%2C%20secondPredicate)%0A%0Aconst%20result%20%3D%20%5B%0A%20%20predicate(15)%2C%0A%20%20predicate(8)%2C%0A%20%20predicate(7)%2C%0A%5D%0A%2F%2F%3D%3E%20%5Btrue%2C%20true%2C%20false%5D">Try this <strong>R.either</strong> example in Rambda REPL</a>
5762
5763<details>
5764
5765<summary>All Typescript definitions</summary>
5766
5767```typescript
5768either(firstPredicate: Pred, secondPredicate: Pred): Pred;
5769either<T>(firstPredicate: Predicate<T>, secondPredicate: Predicate<T>): Predicate<T>;
5770either<T>(firstPredicate: Predicate<T>): (secondPredicate: Predicate<T>) => Predicate<T>;
5771either(firstPredicate: Pred): (secondPredicate: Pred) => Pred;
5772```
5773
5774</details>
5775
5776<details>
5777
5778<summary><strong>R.either</strong> source</summary>
5779
5780```javascript
5781export function either(firstPredicate, secondPredicate){
5782 if (arguments.length === 1){
5783 return _secondPredicate => either(firstPredicate, _secondPredicate)
5784 }
5785
5786 return (...input) =>
5787 Boolean(firstPredicate(...input) || secondPredicate(...input))
5788}
5789```
5790
5791</details>
5792
5793<details>
5794
5795<summary><strong>Tests</strong></summary>
5796
5797```javascript
5798import { either } from './either'
5799
5800test('with multiple inputs', () => {
5801 const between = function (
5802 a, b, c
5803 ){
5804 return a < b && b < c
5805 }
5806 const total20 = function (
5807 a, b, c
5808 ){
5809 return a + b + c === 20
5810 }
5811 const fn = either(between, total20)
5812 expect(fn(
5813 7, 8, 5
5814 )).toBeTrue()
5815})
5816
5817test('skip evaluation of the second expression', () => {
5818 let effect = 'not evaluated'
5819 const F = function (){
5820 return true
5821 }
5822 const Z = function (){
5823 effect = 'Z got evaluated'
5824 }
5825 either(F, Z)()
5826
5827 expect(effect).toBe('not evaluated')
5828})
5829
5830test('case 1', () => {
5831 const firstFn = val => val > 0
5832 const secondFn = val => val * 5 > 10
5833
5834 expect(either(firstFn, secondFn)(1)).toBeTrue()
5835})
5836
5837test('case 2', () => {
5838 const firstFn = val => val > 0
5839 const secondFn = val => val === -10
5840 const fn = either(firstFn)(secondFn)
5841
5842 expect(fn(-10)).toBeTrue()
5843})
5844```
5845
5846</details>
5847
5848<details>
5849
5850<summary><strong>Typescript</strong> test</summary>
5851
5852```typescript
5853import {either} from 'rambda'
5854
5855describe('R.either', () => {
5856 it('with passed type', () => {
5857 const fn = either<number>(
5858 x => x > 1,
5859 x => x % 2 === 0
5860 )
5861 fn // $ExpectType Predicate<number>
5862 const result = fn(2) // $ExpectType boolean
5863 result // $ExpectType boolean
5864 })
5865 it('with passed type - curried', () => {
5866 const fn = either<number>(x => x > 1)(x => x % 2 === 0)
5867 fn // $ExpectType Predicate<number>
5868 const result = fn(2)
5869 result // $ExpectType boolean
5870 })
5871 it('no type passed', () => {
5872 const fn = either(
5873 x => {
5874 x // $ExpectType any
5875 return x > 1
5876 },
5877 x => {
5878 x // $ExpectType any
5879 return x % 2 === 0
5880 }
5881 )
5882 const result = fn(2)
5883 result // $ExpectType boolean
5884 })
5885 it('no type passed - curried', () => {
5886 const fn = either((x: number) => {
5887 x // $ExpectType number
5888 return x > 1
5889 })((x: number) => {
5890 x // $ExpectType number
5891 return x % 2 === 0
5892 })
5893 const result = fn(2)
5894 result // $ExpectType boolean
5895 })
5896})
5897```
5898
5899</details>
5900
5901<details>
5902
5903<summary>1 failed <italic>Ramda.either</italic> specs
5904
5905> :boom: Reason for the failure: Ramda library supports fantasy-land
5906</summary>
5907
5908```javascript
5909var S = require('sanctuary');
5910
5911var R = require('../../../../dist/rambda.js');
5912var eq = require('./shared/eq');
5913describe('either', function() {
5914 it('accepts fantasy-land applicative functors', function() {
5915 var Just = S.Just;
5916 var Nothing = S.Nothing;
5917 eq(R.either(Just(true), Just(true)), Just(true));
5918 eq(R.either(Just(true), Just(false)), Just(true));
5919 eq(R.either(Just(false), Just(false)), Just(false));
5920 eq(R.either(Just(true), Nothing()), Nothing());
5921 eq(R.either(Nothing(), Just(false)), Nothing());
5922 eq(R.either(Nothing(), Nothing()), Nothing());
5923 });
5924});
5925```
5926
5927</details>
5928
5929[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#either)
5930
5931### endsWith
5932
5933```typescript
5934
5935endsWith(target: string, str: string): boolean
5936```
5937
5938Curried version of `String.prototype.endsWith`
5939
5940> :boom: It doesn't work with arrays unlike its corresponding **Ramda** method.
5941
5942```javascript
5943const str = 'foo-bar'
5944const target = '-bar'
5945
5946const result = R.endsWith(target, str)
5947// => true
5948```
5949
5950<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20str%20%3D%20'foo-bar'%0Aconst%20target%20%3D%20'-bar'%0A%0Aconst%20result%20%3D%20R.endsWith(target%2C%20str)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.endsWith</strong> example in Rambda REPL</a>
5951
5952<details>
5953
5954<summary>All Typescript definitions</summary>
5955
5956```typescript
5957endsWith(target: string, str: string): boolean;
5958endsWith(target: string): (str: string) => boolean;
5959```
5960
5961</details>
5962
5963<details>
5964
5965<summary><strong>R.endsWith</strong> source</summary>
5966
5967```javascript
5968export function endsWith(target, str){
5969 if (arguments.length === 1) return _str => endsWith(target, _str)
5970
5971 return str.endsWith(target)
5972}
5973```
5974
5975</details>
5976
5977<details>
5978
5979<summary><strong>Tests</strong></summary>
5980
5981```javascript
5982import { endsWith } from './endsWith'
5983
5984test('happy', () => {
5985 expect(endsWith('bar', 'foo-bar')).toBeTrue()
5986 expect(endsWith('baz')('foo-bar')).toBeFalse()
5987})
5988
5989test('does not work with arrays', () => {
5990 expect(() => endsWith([ 'c' ], [ 'a', 'b', 'c' ])).toThrowWithMessage(Error,
5991 'str.endsWith is not a function')
5992})
5993```
5994
5995</details>
5996
5997<details>
5998
5999<summary><strong>Typescript</strong> test</summary>
6000
6001```typescript
6002import {endsWith} from 'rambda'
6003
6004const target = 'foo'
6005const input = 'foo bar'
6006
6007describe('R.endsWith', () => {
6008 it('happy', () => {
6009 const result = endsWith(target, input)
6010
6011 result // $ExpectType boolean
6012 })
6013 it('curried', () => {
6014 const result = endsWith(target)(input)
6015
6016 result // $ExpectType boolean
6017 })
6018})
6019```
6020
6021</details>
6022
6023<details>
6024
6025<summary>4 failed <italic>Ramda.endsWith</italic> specs
6026
6027> :boom: Reason for the failure: Rambda method doesn't support arrays
6028</summary>
6029
6030```javascript
6031var R = require('../../../../dist/rambda.js');
6032var eq = require('./shared/eq');
6033
6034describe('startsWith', function() {
6035 it('should return true when an array ends with the provided value', function() {
6036 eq(R.endsWith(['c'], ['a', 'b', 'c']), true);
6037 });
6038 it('should return true when an array ends with the provided values', function() {
6039 eq(R.endsWith(['b', 'c'], ['a', 'b', 'c']), true);
6040 });
6041 it('should return false when an array does not end with the provided value', function() {
6042 eq(R.endsWith(['b'], ['a', 'b', 'c']), false);
6043 });
6044 it('should return false when an array does not end with the provided values', function() {
6045 eq(R.endsWith(['a', 'b'], ['a', 'b', 'c']), false);
6046 });
6047});
6048```
6049
6050</details>
6051
6052[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#endsWith)
6053
6054### eqProps
6055
6056```typescript
6057
6058eqProps<T, U>(prop: string, obj1: T, obj2: U): boolean
6059```
6060
6061It returns `true` if property `prop` in `obj1` is equal to property `prop` in `obj2` according to `R.equals`.
6062
6063```javascript
6064const obj1 = {a: 1, b:2}
6065const obj2 = {a: 1, b:3}
6066const result = R.eqProps('a', obj1, obj2)
6067// => true
6068```
6069
6070<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj1%20%3D%20%7Ba%3A%201%2C%20b%3A2%7D%0Aconst%20obj2%20%3D%20%7Ba%3A%201%2C%20b%3A3%7D%0Aconst%20result%20%3D%20R.eqProps('a'%2C%20obj1%2C%20obj2)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.eqProps</strong> example in Rambda REPL</a>
6071
6072<details>
6073
6074<summary>All Typescript definitions</summary>
6075
6076```typescript
6077eqProps<T, U>(prop: string, obj1: T, obj2: U): boolean;
6078eqProps<P extends string>(prop: P): <T, U>(obj1: Record<P, T>, obj2: Record<P, U>) => boolean;
6079eqProps<T>(prop: string, obj1: T): <U>(obj2: U) => boolean;
6080```
6081
6082</details>
6083
6084<details>
6085
6086<summary><strong>R.eqProps</strong> source</summary>
6087
6088```javascript
6089import { curry } from "./curry";
6090import { equals } from "./equals";
6091
6092function eqPropsFn(prop, obj1, obj2) {
6093 if(!obj1 || !obj2){
6094 throw new Error('wrong object inputs are passed to R.eqProps')
6095 }
6096
6097 return equals(obj1[prop], obj2[prop])
6098}
6099
6100export const eqProps = curry(eqPropsFn)
6101```
6102
6103</details>
6104
6105<details>
6106
6107<summary><strong>Tests</strong></summary>
6108
6109```javascript
6110import { eqProps as eqPropsRamda } from 'ramda'
6111
6112import { compareCombinations } from './_internals/testUtils'
6113import { eqProps } from './eqProps'
6114
6115const obj1 = {
6116 a : 1,
6117 b : 2,
6118}
6119const obj2 = {
6120 a : 1,
6121 b : 3,
6122}
6123
6124test('props are equal', () => {
6125 const result = eqProps(
6126 'a', obj1, obj2
6127 )
6128 expect(result).toBeTrue()
6129})
6130
6131test('props are not equal', () => {
6132 const result = eqProps(
6133 'b', obj1, obj2
6134 )
6135 expect(result).toBeFalse()
6136})
6137
6138test('prop does not exist ', () => {
6139 const result = eqProps(
6140 'c', obj1, obj2
6141 )
6142 expect(result).toBeTrue()
6143})
6144
6145const possibleProps = [ 'a', 'a.b', null, false, 0, 1, {}, [] ]
6146
6147const possibleObjects = [
6148 { a : 1 },
6149 {
6150 a : 1,
6151 b : 2,
6152 },
6153 {},
6154 [],
6155 null,
6156 {
6157 a : { b : 1 },
6158 c : 2,
6159 },
6160 {
6161 a : { b : 1 },
6162 c : 3,
6163 },
6164 { a : { b : 2 } },
6165]
6166
6167describe('brute force', () => {
6168 let totalTestsCounter = 0
6169
6170 compareCombinations({
6171 firstInput : possibleProps,
6172 setCounter : () => totalTestsCounter++,
6173 callback : errorsCounters => {
6174 // console.log({ totalTestsCounter })
6175
6176 expect(errorsCounters).toMatchInlineSnapshot(`
6177 Object {
6178 "ERRORS_MESSAGE_MISMATCH": 0,
6179 "ERRORS_TYPE_MISMATCH": 120,
6180 "RESULTS_MISMATCH": 0,
6181 "SHOULD_NOT_THROW": 0,
6182 "SHOULD_THROW": 0,
6183 }
6184 `)
6185 },
6186 secondInput : possibleObjects,
6187 thirdInput : possibleObjects,
6188 fn : eqProps,
6189 fnRamda : eqPropsRamda,
6190 })
6191})
6192```
6193
6194</details>
6195
6196<details>
6197
6198<summary><strong>Typescript</strong> test</summary>
6199
6200```typescript
6201import {eqProps} from 'rambda'
6202
6203const obj1 = {a: {b: 1}, c: 2}
6204const obj2 = {a: {b: 1}, c: 3}
6205
6206describe('R.eqProps', () => {
6207 it('happy', () => {
6208 const result = eqProps('a', obj1, obj2)
6209
6210 result // $ExpectType boolean
6211 })
6212 it('curried', () => {
6213 const result = eqProps('a', obj1)(obj2)
6214
6215 result // $ExpectType boolean
6216 })
6217})
6218```
6219
6220</details>
6221
6222[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#eqProps)
6223
6224### equals
6225
6226```typescript
6227
6228equals<T>(x: T, y: T): boolean
6229```
6230
6231It deeply compares `x` and `y` and returns `true` if they are equal.
6232
6233> :boom: It doesn't handle cyclical data structures and functions
6234
6235```javascript
6236R.equals(
6237 [1, {a:2}, [{b: 3}]],
6238 [1, {a:2}, [{b: 3}]]
6239) // => true
6240```
6241
6242<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.equals(%0A%20%20%5B1%2C%20%7Ba%3A2%7D%2C%20%5B%7Bb%3A%203%7D%5D%5D%2C%0A%20%20%5B1%2C%20%7Ba%3A2%7D%2C%20%5B%7Bb%3A%203%7D%5D%5D%0A)%20%2F%2F%20%3D%3E%20true">Try this <strong>R.equals</strong> example in Rambda REPL</a>
6243
6244<details>
6245
6246<summary>All Typescript definitions</summary>
6247
6248```typescript
6249equals<T>(x: T, y: T): boolean;
6250equals<T>(x: T): (y: T) => boolean;
6251```
6252
6253</details>
6254
6255<details>
6256
6257<summary><strong>R.equals</strong> source</summary>
6258
6259```javascript
6260import { type } from './type'
6261
6262function parseError(maybeError){
6263 const typeofError = maybeError.__proto__.toString()
6264 if (![ 'Error', 'TypeError' ].includes(typeofError)) return []
6265
6266 return [ typeofError, maybeError.message ]
6267}
6268
6269function parseDate(maybeDate){
6270 if (!maybeDate.toDateString) return [ false ]
6271
6272 return [ true, maybeDate.getTime() ]
6273}
6274
6275function parseRegex(maybeRegex){
6276 if (maybeRegex.constructor !== RegExp) return [ false ]
6277
6278 return [ true, maybeRegex.toString() ]
6279}
6280
6281export function equals(a, b){
6282 if (arguments.length === 1) return _b => equals(a, _b)
6283
6284 const aType = type(a)
6285 if (aType !== type(b)) return false
6286 if ([ 'NaN', 'Undefined', 'Null' ].includes(aType)) return true
6287
6288 if (aType === 'Number'){
6289 if (Object.is(-0, a) !== Object.is(-0, b)) return false
6290
6291 return a.toString() === b.toString()
6292 }
6293
6294 if ([ 'String', 'Boolean' ].includes(aType)){
6295 return a.toString() === b.toString()
6296 }
6297
6298 if (aType === 'Array'){
6299 const aClone = Array.from(a)
6300 const bClone = Array.from(b)
6301
6302 if (aClone.toString() !== bClone.toString()){
6303 return false
6304 }
6305
6306 let loopArrayFlag = true
6307 aClone.forEach((aCloneInstance, aCloneIndex) => {
6308 if (loopArrayFlag){
6309 if (
6310 aCloneInstance !== bClone[ aCloneIndex ] &&
6311 !equals(aCloneInstance, bClone[ aCloneIndex ])
6312 ){
6313 loopArrayFlag = false
6314 }
6315 }
6316 })
6317
6318 return loopArrayFlag
6319 }
6320
6321 const aRegex = parseRegex(a)
6322 const bRegex = parseRegex(b)
6323
6324 if (aRegex[ 0 ]){
6325 return bRegex[ 0 ] ? aRegex[ 1 ] === bRegex[ 1 ] : false
6326 } else if (bRegex[ 0 ]) return false
6327
6328 const aDate = parseDate(a)
6329 const bDate = parseDate(b)
6330
6331 if (aDate[ 0 ]){
6332 return bDate[ 0 ] ? aDate[ 1 ] === bDate[ 1 ] : false
6333 } else if (bDate[ 0 ]) return false
6334
6335 const aError = parseError(a)
6336 const bError = parseError(b)
6337
6338 if (aError[ 0 ]){
6339 return bError[ 0 ] ?
6340 aError[ 0 ] === bError[ 0 ] && aError[ 1 ] === bError[ 1 ] :
6341 false
6342 }
6343
6344 if (aType === 'Object'){
6345 const aKeys = Object.keys(a)
6346
6347 if (aKeys.length !== Object.keys(b).length){
6348 return false
6349 }
6350
6351 let loopObjectFlag = true
6352 aKeys.forEach(aKeyInstance => {
6353 if (loopObjectFlag){
6354 const aValue = a[ aKeyInstance ]
6355 const bValue = b[ aKeyInstance ]
6356
6357 if (aValue !== bValue && !equals(aValue, bValue)){
6358 loopObjectFlag = false
6359 }
6360 }
6361 })
6362
6363 return loopObjectFlag
6364 }
6365
6366 return false
6367}
6368```
6369
6370</details>
6371
6372<details>
6373
6374<summary><strong>Tests</strong></summary>
6375
6376```javascript
6377// import { equals } from 'ramda'
6378import { equals } from './equals'
6379
6380test('with array of objects', () => {
6381 const list1 = [ { a : 1 }, [ { b : 2 } ] ]
6382 const list2 = [ { a : 1 }, [ { b : 2 } ] ]
6383 const list3 = [ { a : 1 }, [ { b : 3 } ] ]
6384
6385 expect(equals(list1, list2)).toBeTrue()
6386 expect(equals(list1, list3)).toBeFalse()
6387})
6388
6389test('with regex', () => {
6390 expect(equals(/s/, /s/)).toEqual(true)
6391 expect(equals(/s/, /d/)).toEqual(false)
6392 expect(equals(/a/gi, /a/gi)).toEqual(true)
6393 expect(equals(/a/gim, /a/gim)).toEqual(true)
6394 expect(equals(/a/gi, /a/i)).toEqual(false)
6395})
6396
6397test('not a number', () => {
6398 expect(equals([ NaN ], [ NaN ])).toBeTrue()
6399})
6400
6401test('new number', () => {
6402 expect(equals(new Number(0), new Number(0))).toEqual(true)
6403 expect(equals(new Number(0), new Number(1))).toEqual(false)
6404 expect(equals(new Number(1), new Number(0))).toEqual(false)
6405})
6406
6407test('new string', () => {
6408 expect(equals(new String(''), new String(''))).toEqual(true)
6409 expect(equals(new String(''), new String('x'))).toEqual(false)
6410 expect(equals(new String('x'), new String(''))).toEqual(false)
6411 expect(equals(new String('foo'), new String('foo'))).toEqual(true)
6412 expect(equals(new String('foo'), new String('bar'))).toEqual(false)
6413 expect(equals(new String('bar'), new String('foo'))).toEqual(false)
6414})
6415
6416test('new Boolean', () => {
6417 expect(equals(new Boolean(true), new Boolean(true))).toEqual(true)
6418 expect(equals(new Boolean(false), new Boolean(false))).toEqual(true)
6419 expect(equals(new Boolean(true), new Boolean(false))).toEqual(false)
6420 expect(equals(new Boolean(false), new Boolean(true))).toEqual(false)
6421})
6422
6423test('new Error', () => {
6424 expect(equals(new Error('XXX'), {})).toEqual(false)
6425 expect(equals(new Error('XXX'), new TypeError('XXX'))).toEqual(false)
6426 expect(equals(new Error('XXX'), new Error('YYY'))).toEqual(false)
6427 expect(equals(new Error('XXX'), new Error('XXX'))).toEqual(true)
6428 expect(equals(new Error('XXX'), new TypeError('YYY'))).toEqual(false)
6429})
6430
6431test('with dates', () => {
6432 expect(equals(new Date(0), new Date(0))).toEqual(true)
6433 expect(equals(new Date(1), new Date(1))).toEqual(true)
6434 expect(equals(new Date(0), new Date(1))).toEqual(false)
6435 expect(equals(new Date(1), new Date(0))).toEqual(false)
6436 expect(equals(new Date(0), {})).toEqual(false)
6437 expect(equals({}, new Date(0))).toEqual(false)
6438})
6439
6440test('ramda spec', () => {
6441 expect(equals({}, {})).toEqual(true)
6442
6443 expect(equals({
6444 a : 1,
6445 b : 2,
6446 },
6447 {
6448 a : 1,
6449 b : 2,
6450 })).toEqual(true)
6451
6452 expect(equals({
6453 a : 2,
6454 b : 3,
6455 },
6456 {
6457 b : 3,
6458 a : 2,
6459 })).toEqual(true)
6460
6461 expect(equals({
6462 a : 2,
6463 b : 3,
6464 },
6465 {
6466 a : 3,
6467 b : 3,
6468 })).toEqual(false)
6469
6470 expect(equals({
6471 a : 2,
6472 b : 3,
6473 c : 1,
6474 },
6475 {
6476 a : 2,
6477 b : 3,
6478 })).toEqual(false)
6479})
6480
6481test('works with boolean tuple', () => {
6482 expect(equals([ true, false ], [ true, false ])).toBeTrue()
6483 expect(equals([ true, false ], [ true, true ])).toBeFalse()
6484})
6485
6486test('works with equal objects within array', () => {
6487 const objFirst = {
6488 a : {
6489 b : 1,
6490 c : 2,
6491 d : [ 1 ],
6492 },
6493 }
6494 const objSecond = {
6495 a : {
6496 b : 1,
6497 c : 2,
6498 d : [ 1 ],
6499 },
6500 }
6501
6502 const x = [ 1, 2, objFirst, null, '', [] ]
6503 const y = [ 1, 2, objSecond, null, '', [] ]
6504 expect(equals(x, y)).toBeTrue()
6505})
6506
6507test('works with different objects within array', () => {
6508 const objFirst = { a : { b : 1 } }
6509 const objSecond = { a : { b : 2 } }
6510
6511 const x = [ 1, 2, objFirst, null, '', [] ]
6512 const y = [ 1, 2, objSecond, null, '', [] ]
6513 expect(equals(x, y)).toBeFalse()
6514})
6515
6516test('works with undefined as second argument', () => {
6517 expect(equals(1, undefined)).toBeFalse()
6518
6519 expect(equals(undefined, undefined)).toBeTrue()
6520})
6521
6522test('various examples', () => {
6523 expect(equals([ 1, 2, 3 ])([ 1, 2, 3 ])).toBeTrue()
6524
6525 expect(equals([ 1, 2, 3 ], [ 1, 2 ])).toBeFalse()
6526
6527 expect(equals(1, 1)).toBeTrue()
6528
6529 expect(equals(1, '1')).toBeFalse()
6530
6531 expect(equals({}, {})).toBeTrue()
6532
6533 expect(equals({
6534 a : 1,
6535 b : 2,
6536 },
6537 {
6538 b : 2,
6539 a : 1,
6540 })).toBeTrue()
6541
6542 expect(equals({
6543 a : 1,
6544 b : 2,
6545 },
6546 {
6547 a : 1,
6548 b : 1,
6549 })).toBeFalse()
6550
6551 expect(equals({
6552 a : 1,
6553 b : false,
6554 },
6555 {
6556 a : 1,
6557 b : 1,
6558 })).toBeFalse()
6559
6560 expect(equals({
6561 a : 1,
6562 b : 2,
6563 },
6564 {
6565 b : 2,
6566 a : 1,
6567 c : 3,
6568 })).toBeFalse()
6569
6570 expect(equals({
6571 x : {
6572 a : 1,
6573 b : 2,
6574 },
6575 },
6576 {
6577 x : {
6578 b : 2,
6579 a : 1,
6580 c : 3,
6581 },
6582 })).toBeFalse()
6583
6584 expect(equals({
6585 a : 1,
6586 b : 2,
6587 },
6588 {
6589 b : 3,
6590 a : 1,
6591 })).toBeFalse()
6592
6593 expect(equals({ a : { b : { c : 1 } } }, { a : { b : { c : 1 } } })).toBeTrue()
6594
6595 expect(equals({ a : { b : { c : 1 } } }, { a : { b : { c : 2 } } })).toBeFalse()
6596
6597 expect(equals({ a : {} }, { a : {} })).toBeTrue()
6598
6599 expect(equals('', '')).toBeTrue()
6600
6601 expect(equals('foo', 'foo')).toBeTrue()
6602
6603 expect(equals('foo', 'bar')).toBeFalse()
6604
6605 expect(equals(0, false)).toBeFalse()
6606
6607 expect(equals(/\s/g, null)).toBeFalse()
6608
6609 expect(equals(null, null)).toBeTrue()
6610
6611 expect(equals(false)(null)).toBeFalse()
6612})
6613
6614test('with custom functions', () => {
6615 function foo(){
6616 return 1
6617 }
6618 foo.prototype.toString = () => ''
6619 const result = equals(foo, foo)
6620
6621 expect(result).toBeFalse()
6622})
6623
6624test('with classes', () => {
6625 class Foo{}
6626 const foo = new Foo()
6627 const result = equals(foo, foo)
6628
6629 expect(result).toBeTrue()
6630})
6631
6632test('with negative zero', () => {
6633 expect(equals(-0, -0)).toBeTrue()
6634 expect(equals(-0, 0)).toBeFalse()
6635 expect(equals(0, 0)).toBeTrue()
6636 expect(equals(-0, 1)).toBeFalse()
6637})
6638```
6639
6640</details>
6641
6642<details>
6643
6644<summary><strong>Typescript</strong> test</summary>
6645
6646```typescript
6647import {equals} from 'rambda'
6648
6649describe('R.equals', () => {
6650 it('happy', () => {
6651 const result = equals(4, 1)
6652 result // $ExpectType boolean
6653 })
6654 it('with object', () => {
6655 const foo = {a: 1}
6656 const bar = {a: 2}
6657 const result = equals(foo, bar)
6658 result // $ExpectType boolean
6659 })
6660 it('curried', () => {
6661 const result = equals(4)(1)
6662
6663 result // $ExpectType boolean
6664 })
6665})
6666```
6667
6668</details>
6669
6670<details>
6671
6672<summary>14 failed <italic>Ramda.equals</italic> specs
6673
6674> :boom: Reason for the failure: Rambda method doesn't support recursive data structures, objects with same enumerable properties, map/weakmap type of variables | Ramda dispatches to `equals` method recursively | Rambda method doesn't support equality of functions
6675</summary>
6676
6677```javascript
6678/* global Map, Set, WeakMap, WeakSet */
6679
6680var R = require('../../../../dist/rambda.js');
6681var eq = require('./shared/eq');
6682describe('equals', function() {
6683 var a = [];
6684 var b = a;
6685 it('never considers Boolean primitive equal to Boolean object', function() {
6686 eq(R.equals(true, new Boolean(true)), false);
6687 eq(R.equals(new Boolean(true), true), false);
6688 eq(R.equals(false, new Boolean(false)), false);
6689 eq(R.equals(new Boolean(false), false), false);
6690 });
6691 it('never considers number primitive equal to Number object', function() {
6692 eq(R.equals(0, new Number(0)), false);
6693 eq(R.equals(new Number(0), 0), false);
6694 });
6695 it('never considers string primitive equal to String object', function() {
6696 eq(R.equals('', new String('')), false);
6697 eq(R.equals(new String(''), ''), false);
6698 eq(R.equals('x', new String('x')), false);
6699 eq(R.equals(new String('x'), 'x'), false);
6700 });
6701 var supportsSticky = false;
6702 try { RegExp('', 'y'); supportsSticky = true; } catch (e) {}
6703 var supportsUnicode = false;
6704 try { RegExp('', 'u'); supportsUnicode = true; } catch (e) {}
6705 var listA = [1, 2, 3];
6706 var listB = [1, 3, 2];
6707 var c = {}; c.v = c;
6708 var d = {}; d.v = d;
6709 var e = []; e.push(e);
6710 var f = []; f.push(f);
6711 var nestA = {a:[1, 2, {c:1}], b:1};
6712 var nestB = {a:[1, 2, {c:1}], b:1};
6713 var nestC = {a:[1, 2, {c:2}], b:1};
6714 it('handles recursive data structures', function() {
6715 eq(R.equals(c, d), true);
6716 eq(R.equals(e, f), true);
6717 eq(R.equals(nestA, nestB), true);
6718 eq(R.equals(nestA, nestC), false);
6719 });
6720 it('requires that both objects have the same enumerable properties with the same values', function() {
6721 var a1 = [];
6722 var a2 = [];
6723 a2.x = 0;
6724 var b1 = new Boolean(false);
6725 var b2 = new Boolean(false);
6726 b2.x = 0;
6727 var d1 = new Date(0);
6728 var d2 = new Date(0);
6729 d2.x = 0;
6730 var n1 = new Number(0);
6731 var n2 = new Number(0);
6732 n2.x = 0;
6733 var r1 = /(?:)/;
6734 var r2 = /(?:)/;
6735 r2.x = 0;
6736 var s1 = new String('');
6737 var s2 = new String('');
6738 s2.x = 0;
6739 eq(R.equals(a1, a2), false);
6740 eq(R.equals(b1, b2), false);
6741 eq(R.equals(d1, d2), false);
6742 eq(R.equals(n1, n2), false);
6743 eq(R.equals(r1, r2), false);
6744 eq(R.equals(s1, s2), false);
6745 });
6746 if (typeof ArrayBuffer !== 'undefined' && typeof Int8Array !== 'undefined') {
6747 var typArr1 = new ArrayBuffer(10);
6748 typArr1[0] = 1;
6749 var typArr2 = new ArrayBuffer(10);
6750 typArr2[0] = 1;
6751 var typArr3 = new ArrayBuffer(10);
6752 var intTypArr = new Int8Array(typArr1);
6753 typArr3[0] = 0;
6754 it('handles typed arrays', function() {
6755 eq(R.equals(typArr1, typArr2), true);
6756 eq(R.equals(typArr1, typArr3), false);
6757 eq(R.equals(typArr1, intTypArr), false);
6758 });
6759 }
6760 if (typeof Promise !== 'undefined') {
6761 it('compares Promise objects by identity', function() {
6762 var p = Promise.resolve(42);
6763 var q = Promise.resolve(42);
6764 eq(R.equals(p, p), true);
6765 eq(R.equals(p, q), false);
6766 });
6767 }
6768 if (typeof Map !== 'undefined') {
6769 it('compares Map objects by value', function() {
6770 eq(R.equals(new Map([]), new Map([])), true);
6771 eq(R.equals(new Map([]), new Map([[1, 'a']])), false);
6772 eq(R.equals(new Map([[1, 'a']]), new Map([])), false);
6773 eq(R.equals(new Map([[1, 'a']]), new Map([[1, 'a']])), true);
6774 eq(R.equals(new Map([[1, 'a'], [2, 'b']]), new Map([[2, 'b'], [1, 'a']])), true);
6775 eq(R.equals(new Map([[1, 'a']]), new Map([[2, 'a']])), false);
6776 eq(R.equals(new Map([[1, 'a']]), new Map([[1, 'b']])), false);
6777 eq(R.equals(new Map([[1, 'a'], [2, new Map([[3, 'c']])]]), new Map([[1, 'a'], [2, new Map([[3, 'c']])]])), true);
6778 eq(R.equals(new Map([[1, 'a'], [2, new Map([[3, 'c']])]]), new Map([[1, 'a'], [2, new Map([[3, 'd']])]])), false);
6779 eq(R.equals(new Map([[[1, 2, 3], [4, 5, 6]]]), new Map([[[1, 2, 3], [4, 5, 6]]])), true);
6780 eq(R.equals(new Map([[[1, 2, 3], [4, 5, 6]]]), new Map([[[1, 2, 3], [7, 8, 9]]])), false);
6781 });
6782 it('dispatches to `equals` method recursively in Set', function() {
6783 var a = new Map();
6784 var b = new Map();
6785 a.set(a, a);
6786 eq(R.equals(a, b), false);
6787 a.set(b, b);
6788 b.set(b, b);
6789 b.set(a, a);
6790 eq(R.equals(a, b), true);
6791 });
6792 }
6793 if (typeof Set !== 'undefined') {
6794 it('compares Set objects by value', function() {
6795 eq(R.equals(new Set([]), new Set([])), true);
6796 eq(R.equals(new Set([]), new Set([1])), false);
6797 eq(R.equals(new Set([1]), new Set([])), false);
6798 eq(R.equals(new Set([1, 2]), new Set([2, 1])), true);
6799 eq(R.equals(new Set([1, new Set([2, new Set([3])])]), new Set([1, new Set([2, new Set([3])])])), true);
6800 eq(R.equals(new Set([1, new Set([2, new Set([3])])]), new Set([1, new Set([2, new Set([4])])])), false);
6801 eq(R.equals(new Set([[1, 2, 3], [4, 5, 6]]), new Set([[1, 2, 3], [4, 5, 6]])), true);
6802 eq(R.equals(new Set([[1, 2, 3], [4, 5, 6]]), new Set([[1, 2, 3], [7, 8, 9]])), false);
6803 });
6804 it('dispatches to `equals` method recursively in Set', function() {
6805 var a = new Set();
6806 var b = new Set();
6807 a.add(a);
6808 eq(R.equals(a, b), false);
6809 a.add(b);
6810 b.add(b);
6811 b.add(a);
6812 eq(R.equals(a, b), true);
6813 });
6814 }
6815 if (typeof WeakMap !== 'undefined') {
6816 it('compares WeakMap objects by identity', function() {
6817 var m = new WeakMap([]);
6818 eq(R.equals(m, m), true);
6819 eq(R.equals(m, new WeakMap([])), false);
6820 });
6821 }
6822 if (typeof WeakSet !== 'undefined') {
6823 it('compares WeakSet objects by identity', function() {
6824 var s = new WeakSet([]);
6825 eq(R.equals(s, s), true);
6826 eq(R.equals(s, new WeakSet([])), false);
6827 });
6828 }
6829 it('dispatches to `equals` method recursively', function() {
6830 function Left(x) { this.value = x; }
6831 Left.prototype.equals = function(x) {
6832 return x instanceof Left && R.equals(x.value, this.value);
6833 };
6834 function Right(x) { this.value = x; }
6835 Right.prototype.equals = function(x) {
6836 return x instanceof Right && R.equals(x.value, this.value);
6837 };
6838 eq(R.equals(new Left([42]), new Left([42])), true);
6839 eq(R.equals(new Left([42]), new Left([43])), false);
6840 eq(R.equals(new Left(42), {value: 42}), false);
6841 eq(R.equals({value: 42}, new Left(42)), false);
6842 eq(R.equals(new Left(42), new Right(42)), false);
6843 eq(R.equals(new Right(42), new Left(42)), false);
6844 eq(R.equals([new Left(42)], [new Left(42)]), true);
6845 eq(R.equals([new Left(42)], [new Right(42)]), false);
6846 eq(R.equals([new Right(42)], [new Left(42)]), false);
6847 eq(R.equals([new Right(42)], [new Right(42)]), true);
6848 });
6849});
6850```
6851
6852</details>
6853
6854[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#equals)
6855
6856### evolve
6857
6858```typescript
6859
6860evolve<T, U>(rules: Array<(x: T) => U>, list: T[]): U[]
6861```
6862
6863It takes object or array of functions as set of rules. These `rules` are applied to the `iterable` input to produce the result.
6864
6865> :boom: Error handling of this method differs between Ramda and Rambda. Ramda for some wrong inputs returns result and for other - it returns one of the inputs. Rambda simply throws when inputs are not correct. Full details for this mismatch are listed in `source/_snapshots/evolve.spec.js.snap` file.
6866
6867```javascript
6868const rules = {
6869 foo : add(1),
6870 bar : add(-1),
6871}
6872const input = {
6873 a : 1,
6874 foo : 2,
6875 bar : 3,
6876}
6877const result = evolve(rules, input)
6878const expected = {
6879 a : 1,
6880 foo : 3,
6881 bar : 2,
6882})
6883// => `result` is equal to `expected`
6884```
6885
6886<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20rules%20%3D%20%7B%0A%20%20foo%20%3A%20add(1)%2C%0A%20%20bar%20%3A%20add(-1)%2C%0A%7D%0Aconst%20input%20%3D%20%7B%0A%20%20a%20%20%20%3A%201%2C%0A%20%20foo%20%3A%202%2C%0A%20%20bar%20%3A%203%2C%0A%7D%0Aconst%20result%20%3D%20evolve(rules%2C%20input)%0Aconst%20expected%20%3D%20%7B%0A%20%20a%20%20%20%3A%201%2C%0A%20%20foo%20%3A%203%2C%0A%20%20bar%20%3A%202%2C%0A%7D)%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.evolve</strong> example in Rambda REPL</a>
6887
6888<details>
6889
6890<summary>All Typescript definitions</summary>
6891
6892```typescript
6893evolve<T, U>(rules: Array<(x: T) => U>, list: T[]): U[];
6894evolve<T, U>(rules: Array<(x: T) => U>) : (list: T[]) => U[];
6895evolve<E extends Evolver, V extends Evolvable<E>>(rules: E, obj: V): Evolve<V, E>;
6896evolve<E extends Evolver>(rules: E): <V extends Evolvable<E>>(obj: V) => Evolve<V, E>;
6897```
6898
6899</details>
6900
6901<details>
6902
6903<summary><strong>R.evolve</strong> source</summary>
6904
6905```javascript
6906import { _isArray } from './_internals/_isArray'
6907import { mapArray, mapObject } from './map'
6908import { type } from './type'
6909
6910export function evolveArray(rules, list){
6911 return mapArray(
6912 (x, i) => {
6913 if (type(rules[ i ]) === 'Function'){
6914 return rules[ i ](x)
6915 }
6916
6917 return x
6918 },
6919 list,
6920 true
6921 )
6922}
6923
6924export function evolveObject(rules, iterable){
6925 return mapObject((x, prop) => {
6926 if (type(x) === 'Object'){
6927 const typeRule = type(rules[ prop ])
6928 if (typeRule === 'Function'){
6929 return rules[ prop ](x)
6930 }
6931 if (typeRule === 'Object'){
6932 return evolve(rules[ prop ], x)
6933 }
6934
6935 return x
6936 }
6937 if (type(rules[ prop ]) === 'Function'){
6938 return rules[ prop ](x)
6939 }
6940
6941 return x
6942 }, iterable)
6943}
6944
6945export function evolve(rules, iterable){
6946 if (arguments.length === 1){
6947 return _iterable => evolve(rules, _iterable)
6948 }
6949 const rulesType = type(rules)
6950 const iterableType = type(iterable)
6951
6952 if (iterableType !== rulesType){
6953 throw new Error('iterableType !== rulesType')
6954 }
6955
6956 if (![ 'Object', 'Array' ].includes(rulesType)){
6957 throw new Error(`'iterable' and 'rules' are from wrong type ${ rulesType }`)
6958 }
6959
6960 if (iterableType === 'Object'){
6961 return evolveObject(rules, iterable)
6962 }
6963
6964 return evolveArray(rules, iterable)
6965}
6966```
6967
6968</details>
6969
6970<details>
6971
6972<summary><strong>Tests</strong></summary>
6973
6974```javascript
6975import { evolve as evolveRamda } from "ramda";
6976
6977import { add } from "../rambda.js";
6978import { compareCombinations, compareToRamda } from "./_internals/testUtils";
6979import { evolve } from "./evolve";
6980
6981test("happy", () => {
6982 const rules = {
6983 foo: add(1),
6984 bar: add(-1),
6985 };
6986 const input = {
6987 a: 1,
6988 foo: 2,
6989 bar: 3,
6990 };
6991 const result = evolve(rules, input);
6992 expect(result).toEqual({
6993 a: 1,
6994 foo: 3,
6995 bar: 2,
6996 });
6997});
6998
6999test("is recursive", () => {
7000 const rules = {
7001 nested: {
7002 second: add(-1),
7003 third: add(1),
7004 },
7005 };
7006 const object = {
7007 first: 1,
7008 nested: {
7009 second: 2,
7010 third: 3,
7011 },
7012 };
7013 const expected = {
7014 first: 1,
7015 nested: {
7016 second: 1,
7017 third: 4,
7018 },
7019 };
7020 const result = evolve(rules, object);
7021 expect(result).toEqual(expected);
7022});
7023
7024test("ignores primitive value rulesormations", () => {
7025 const rules = {
7026 n: 2,
7027 m: "foo",
7028 };
7029 const object = {
7030 n: 0,
7031 m: 1,
7032 };
7033 const expected = {
7034 n: 0,
7035 m: 1,
7036 };
7037 const result = evolve(rules, object);
7038 expect(result).toEqual(expected);
7039});
7040
7041test("with array", () => {
7042 const rules = [add(1), add(-1)];
7043 const list = [100, 1400];
7044 const expected = [101, 1399];
7045 const result = evolve(rules, list);
7046 expect(result).toEqual(expected);
7047});
7048
7049const rulesObject = { a: add(1) };
7050const rulesList = [add(1)];
7051const possibleIterables = [null, undefined, "", 42, [], [1], { a: 1 }];
7052const possibleRules = [...possibleIterables, rulesList, rulesObject];
7053
7054describe("brute force", () => {
7055 compareCombinations({
7056 firstInput: possibleRules,
7057 callback: (errorsCounters) => {
7058 expect(errorsCounters).toMatchInlineSnapshot(`
7059 Object {
7060 "ERRORS_MESSAGE_MISMATCH": 0,
7061 "ERRORS_TYPE_MISMATCH": 4,
7062 "RESULTS_MISMATCH": 0,
7063 "SHOULD_NOT_THROW": 51,
7064 "SHOULD_THROW": 0,
7065 }
7066 `);
7067 },
7068 secondInput: possibleIterables,
7069 fn: evolve,
7070 fnRamda: evolveRamda,
7071 });
7072});
7073```
7074
7075</details>
7076
7077<details>
7078
7079<summary><strong>Typescript</strong> test</summary>
7080
7081```typescript
7082import {evolve, add} from 'rambda'
7083
7084describe('R.evolve', () => {
7085 it('happy', () => {
7086 const input = {
7087 foo: 2,
7088 nested: {
7089 a: 1,
7090 bar: 3,
7091 },
7092 }
7093 const rules = {
7094 foo: add(1),
7095 nested: {
7096 a: add(-1),
7097 bar: add(1),
7098 },
7099 }
7100 const result = evolve(rules, input)
7101 const curriedResult = evolve(rules)(input)
7102
7103 result.nested.a // $ExpectType number
7104 curriedResult.nested.a // $ExpectType number
7105 result.nested.bar // $ExpectType number
7106 result.foo // $ExpectType number
7107 })
7108 it('with array', () => {
7109 const rules = [String, String]
7110 const input = [100, 1400]
7111 const result = evolve(rules, input)
7112 const curriedResult = evolve(rules)(input)
7113 result // $ExpectType string[]
7114 curriedResult // $ExpectType string[]
7115 })
7116})
7117```
7118
7119</details>
7120
7121*1 failed Ramda.evolve specs*
7122
7123> :boom: Reason for the failure: Rambda throws if `iterable` input is neither array nor object
7124
7125[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#evolve)
7126
7127### F
7128
7129```typescript
7130
7131F(): boolean
7132```
7133
7134```javascript
7135F() // => false
7136```
7137
7138<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20F()%20%2F%2F%20%3D%3E%20false">Try this <strong>R.F</strong> example in Rambda REPL</a>
7139
7140<details>
7141
7142<summary>All Typescript definitions</summary>
7143
7144```typescript
7145F(): boolean;
7146```
7147
7148</details>
7149
7150<details>
7151
7152<summary><strong>R.F</strong> source</summary>
7153
7154```javascript
7155export function F(){
7156 return false
7157}
7158```
7159
7160</details>
7161
7162[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#F)
7163
7164### filter
7165
7166```typescript
7167
7168filter<T>(predicate: FilterFunctionArray<T>): (input: readonly T[]) => T[]
7169```
7170
7171It filters list or object `input` using a `predicate` function.
7172
7173```javascript
7174const list = [3, 4, 3, 2]
7175const listPredicate = x => x > 2
7176
7177const object = {abc: 'fo', xyz: 'bar', baz: 'foo'}
7178const objectPredicate = (x, prop) => x.length + prop.length > 5
7179
7180const result = [
7181 R.filter(listPredicate, list),
7182 R.filter(objectPredicate, object)
7183]
7184// => [ [3, 4], { xyz: 'bar', baz: 'foo'} ]
7185```
7186
7187<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B3%2C%204%2C%203%2C%202%5D%0Aconst%20listPredicate%20%3D%20x%20%3D%3E%20x%20%3E%202%0A%0Aconst%20object%20%3D%20%7Babc%3A%20'fo'%2C%20xyz%3A%20'bar'%2C%20baz%3A%20'foo'%7D%0Aconst%20objectPredicate%20%3D%20(x%2C%20prop)%20%3D%3E%20x.length%20%2B%20prop.length%20%3E%205%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.filter(listPredicate%2C%20list)%2C%0A%20%20R.filter(objectPredicate%2C%20object)%0A%5D%0A%2F%2F%20%3D%3E%20%5B%20%5B3%2C%204%5D%2C%20%7B%20xyz%3A%20'bar'%2C%20baz%3A%20'foo'%7D%20%5D">Try this <strong>R.filter</strong> example in Rambda REPL</a>
7188
7189<details>
7190
7191<summary>All Typescript definitions</summary>
7192
7193```typescript
7194filter<T>(predicate: FilterFunctionArray<T>): (input: readonly T[]) => T[];
7195filter<T>(predicate: FilterFunctionArray<T>, input: readonly T[]): T[];
7196filter<T, U>(predicate: FilterFunctionObject<T>): (x: Dictionary<T>) => Dictionary<T>;
7197filter<T>(predicate: FilterFunctionObject<T>, x: Dictionary<T>): Dictionary<T>;
7198```
7199
7200</details>
7201
7202<details>
7203
7204<summary><strong>R.filter</strong> source</summary>
7205
7206```javascript
7207import { _isArray } from './_internals/_isArray'
7208
7209export function filterObject(fn, obj){
7210 const willReturn = {}
7211
7212 for (const prop in obj){
7213 if (fn(
7214 obj[ prop ], prop, obj
7215 )){
7216 willReturn[ prop ] = obj[ prop ]
7217 }
7218 }
7219
7220 return willReturn
7221}
7222
7223export function filterArray(
7224 predicate, list, indexed = false
7225){
7226 let index = 0
7227 const len = list.length
7228 const willReturn = []
7229
7230 while (index < len){
7231 const predicateResult = indexed ?
7232 predicate(list[ index ], index) :
7233 predicate(list[ index ])
7234 if (predicateResult){
7235 willReturn.push(list[ index ])
7236 }
7237
7238 index++
7239 }
7240
7241 return willReturn
7242}
7243
7244export function filter(predicate, iterable){
7245 if (arguments.length === 1){
7246 return _iterable => filter(predicate, _iterable)
7247 }
7248 if (!iterable) return []
7249 if (_isArray(iterable)) return filterArray(predicate, iterable)
7250
7251 return filterObject(predicate, iterable)
7252}
7253```
7254
7255</details>
7256
7257<details>
7258
7259<summary><strong>Tests</strong></summary>
7260
7261```javascript
7262import Ramda from 'ramda'
7263
7264import { F } from './F'
7265import { filter } from './filter'
7266import { T } from './T'
7267
7268const sampleObject = {
7269 a : 1,
7270 b : 2,
7271 c : 3,
7272 d : 4,
7273}
7274
7275test('happy', () => {
7276 const isEven = n => n % 2 === 0
7277
7278 expect(filter(isEven, [ 1, 2, 3, 4 ])).toEqual([ 2, 4 ])
7279 expect(filter(isEven, {
7280 a : 1,
7281 b : 2,
7282 d : 3,
7283 })).toEqual({ b : 2 })
7284})
7285
7286test('bad inputs difference between Ramda and Rambda', () => {
7287 expect(filter(T)(undefined)).toEqual([])
7288 expect(filter(F, null)).toEqual([])
7289 expect(() => Ramda.filter(T, null)).toThrowWithMessage(TypeError,
7290 'Cannot read property \'filter\' of null')
7291 expect(() => Ramda.filter(T, undefined)).toThrowWithMessage(TypeError,
7292 'Cannot read property \'filter\' of undefined')
7293})
7294
7295test('predicate when input is object', () => {
7296 const obj = {
7297 a : 1,
7298 b : 2,
7299 }
7300 const predicate = (
7301 val, prop, inputObject
7302 ) => {
7303 expect(inputObject).toEqual(obj)
7304 expect(typeof prop).toEqual('string')
7305
7306 return val < 2
7307 }
7308 expect(filter(predicate, obj)).toEqual({ a : 1 })
7309})
7310
7311test('with object', () => {
7312 const isEven = n => n % 2 === 0
7313 const result = filter(isEven, sampleObject)
7314 const expectedResult = {
7315 b : 2,
7316 d : 4,
7317 }
7318
7319 expect(result).toEqual(expectedResult)
7320})
7321```
7322
7323</details>
7324
7325<details>
7326
7327<summary><strong>Typescript</strong> test</summary>
7328
7329```typescript
7330import {filter} from 'rambda'
7331
7332const list = [1, 2, 3]
7333const obj = {a: 1, b: 2}
7334
7335describe('R.filter with array', () => {
7336 it('happy', () => {
7337 const result = filter<number>(x => {
7338 x // $ExpectType number
7339 return x > 1
7340 }, list)
7341 result // $ExpectType number[]
7342 })
7343 it('curried', () => {
7344 const result = filter<number>(x => {
7345 x // $ExpectType number
7346 return x > 1
7347 })(list)
7348 result // $ExpectType number[]
7349 })
7350})
7351
7352describe('R.filter with objects', () => {
7353 it('happy', () => {
7354 const result = filter<number>((val, prop, origin) => {
7355 val // $ExpectType number
7356 prop // $ExpectType string
7357 origin // $ExpectType Dictionary<number>
7358
7359 return val > 1
7360 }, obj)
7361 result // $ExpectType Dictionary<number>
7362 })
7363 it('curried version requires second dummy type', () => {
7364 const result = filter<number, any>((val, prop, origin) => {
7365 val // $ExpectType number
7366 prop // $ExpectType string
7367 origin // $ExpectType Dictionary<number>
7368
7369 return val > 1
7370 })(obj)
7371 result // $ExpectType Dictionary<number>
7372 })
7373})
7374```
7375
7376</details>
7377
7378<details>
7379
7380<summary>1 failed <italic>Ramda.filter</italic> specs
7381
7382> :boom: Reason for the failure: Ramda method dispatches to `filter` method of object
7383</summary>
7384
7385```javascript
7386var R = require('../../../../dist/rambda.js');
7387var eq = require('./shared/eq');
7388var Maybe = require('./shared/Maybe');
7389
7390describe('filter', function() {
7391 var even = function(x) {return x % 2 === 0;};
7392 it('dispatches to passed-in non-Array object with a `filter` method', function() {
7393 var f = {filter: function(f) { return f('called f.filter'); }};
7394 eq(R.filter(function(s) { return s; }, f), 'called f.filter');
7395 });
7396 it('correctly uses fantasy-land implementations', function() {
7397 var m1 = Maybe.Just(-1);
7398 var m2 = R.filter(function(x) { return x > 0; } , m1);
7399 eq(m2.isNothing, true);
7400 });
7401});
7402```
7403
7404</details>
7405
7406[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#filter)
7407
7408### find
7409
7410```typescript
7411
7412find<T>(predicate: (x: T) => boolean, list: readonly T[]): T | undefined
7413```
7414
7415It returns the first element of `list` that satisfy the `predicate`.
7416
7417If there is no such element, it returns `undefined`.
7418
7419```javascript
7420const predicate = x => R.type(x.foo) === 'Number'
7421const list = [{foo: 'bar'}, {foo: 1}]
7422
7423const result = R.find(predicate, list)
7424// => {foo: 1}
7425```
7426
7427<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20predicate%20%3D%20x%20%3D%3E%20R.type(x.foo)%20%3D%3D%3D%20'Number'%0Aconst%20list%20%3D%20%5B%7Bfoo%3A%20'bar'%7D%2C%20%7Bfoo%3A%201%7D%5D%0A%0Aconst%20result%20%3D%20R.find(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20%7Bfoo%3A%201%7D">Try this <strong>R.find</strong> example in Rambda REPL</a>
7428
7429<details>
7430
7431<summary>All Typescript definitions</summary>
7432
7433```typescript
7434find<T>(predicate: (x: T) => boolean, list: readonly T[]): T | undefined;
7435find<T>(predicate: (x: T) => boolean): (list: readonly T[]) => T | undefined;
7436```
7437
7438</details>
7439
7440<details>
7441
7442<summary><strong>R.find</strong> source</summary>
7443
7444```javascript
7445export function find(predicate, list){
7446 if (arguments.length === 1) return _list => find(predicate, _list)
7447
7448 let index = 0
7449 const len = list.length
7450
7451 while (index < len){
7452 const x = list[ index ]
7453 if (predicate(x)){
7454 return x
7455 }
7456
7457 index++
7458 }
7459}
7460```
7461
7462</details>
7463
7464<details>
7465
7466<summary><strong>Tests</strong></summary>
7467
7468```javascript
7469import { find } from './find'
7470import { propEq } from './propEq'
7471
7472const list = [ { a : 1 }, { a : 2 }, { a : 3 } ]
7473
7474test('happy', () => {
7475 const fn = propEq('a', 2)
7476 expect(find(fn, list)).toEqual({ a : 2 })
7477})
7478
7479test('with curry', () => {
7480 const fn = propEq('a', 4)
7481 expect(find(fn)(list)).toBeUndefined()
7482})
7483
7484test('with empty list', () => {
7485 expect(find(() => true, [])).toBeUndefined()
7486})
7487```
7488
7489</details>
7490
7491<details>
7492
7493<summary><strong>Typescript</strong> test</summary>
7494
7495```typescript
7496import {find} from 'rambda'
7497
7498const list = [1, 2, 3]
7499
7500describe('R.find', () => {
7501 it('happy', () => {
7502 const predicate = (x: number) => x > 2
7503 const result = find(predicate, list)
7504 result // $ExpectType number | undefined
7505 })
7506 it('curried', () => {
7507 const predicate = (x: number) => x > 2
7508 const result = find(predicate)(list)
7509 result // $ExpectType number | undefined
7510 })
7511})
7512```
7513
7514</details>
7515
7516[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#find)
7517
7518### findIndex
7519
7520```typescript
7521
7522findIndex<T>(predicate: (x: T) => boolean, list: readonly T[]): number
7523```
7524
7525It returns the index of the first element of `list` satisfying the `predicate` function.
7526
7527If there is no such element, then `-1` is returned.
7528
7529```javascript
7530const predicate = x => R.type(x.foo) === 'Number'
7531const list = [{foo: 'bar'}, {foo: 1}]
7532
7533const result = R.findIndex(predicate, list)
7534// => 1
7535```
7536
7537<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20predicate%20%3D%20x%20%3D%3E%20R.type(x.foo)%20%3D%3D%3D%20'Number'%0Aconst%20list%20%3D%20%5B%7Bfoo%3A%20'bar'%7D%2C%20%7Bfoo%3A%201%7D%5D%0A%0Aconst%20result%20%3D%20R.findIndex(predicate%2C%20list)%0A%2F%2F%20%3D%3E%201">Try this <strong>R.findIndex</strong> example in Rambda REPL</a>
7538
7539<details>
7540
7541<summary>All Typescript definitions</summary>
7542
7543```typescript
7544findIndex<T>(predicate: (x: T) => boolean, list: readonly T[]): number;
7545findIndex<T>(predicate: (x: T) => boolean): (list: readonly T[]) => number;
7546```
7547
7548</details>
7549
7550<details>
7551
7552<summary><strong>R.findIndex</strong> source</summary>
7553
7554```javascript
7555export function findIndex(predicate, list){
7556 if (arguments.length === 1) return _list => findIndex(predicate, _list)
7557
7558 const len = list.length
7559 let index = -1
7560
7561 while (++index < len){
7562 if (predicate(list[ index ])){
7563 return index
7564 }
7565 }
7566
7567 return -1
7568}
7569```
7570
7571</details>
7572
7573<details>
7574
7575<summary><strong>Tests</strong></summary>
7576
7577```javascript
7578import { findIndex } from './findIndex'
7579import { propEq } from './propEq'
7580
7581const list = [ { a : 1 }, { a : 2 }, { a : 3 } ]
7582
7583test('happy', () => {
7584 expect(findIndex(propEq('a', 2), list)).toEqual(1)
7585
7586 expect(findIndex(propEq('a', 1))(list)).toEqual(0)
7587
7588 expect(findIndex(propEq('a', 4))(list)).toEqual(-1)
7589})
7590```
7591
7592</details>
7593
7594<details>
7595
7596<summary><strong>Typescript</strong> test</summary>
7597
7598```typescript
7599import {findIndex} from 'rambda'
7600
7601const list = [1, 2, 3]
7602
7603describe('R.findIndex', () => {
7604 it('happy', () => {
7605 const predicate = (x: number) => x > 2
7606 const result = findIndex(predicate, list)
7607 result // $ExpectType number
7608 })
7609 it('curried', () => {
7610 const predicate = (x: number) => x > 2
7611 const result = findIndex(predicate)(list)
7612 result // $ExpectType number
7613 })
7614})
7615```
7616
7617</details>
7618
7619[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#findIndex)
7620
7621### findLast
7622
7623```typescript
7624
7625findLast<T>(fn: (x: T) => boolean, list: readonly T[]): T | undefined
7626```
7627
7628It returns the last element of `list` satisfying the `predicate` function.
7629
7630If there is no such element, then `undefined` is returned.
7631
7632```javascript
7633const predicate = x => R.type(x.foo) === 'Number'
7634const list = [{foo: 0}, {foo: 1}]
7635
7636const result = R.findLast(predicate, list)
7637// => {foo: 1}
7638```
7639
7640<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20predicate%20%3D%20x%20%3D%3E%20R.type(x.foo)%20%3D%3D%3D%20'Number'%0Aconst%20list%20%3D%20%5B%7Bfoo%3A%200%7D%2C%20%7Bfoo%3A%201%7D%5D%0A%0Aconst%20result%20%3D%20R.findLast(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20%7Bfoo%3A%201%7D">Try this <strong>R.findLast</strong> example in Rambda REPL</a>
7641
7642<details>
7643
7644<summary>All Typescript definitions</summary>
7645
7646```typescript
7647findLast<T>(fn: (x: T) => boolean, list: readonly T[]): T | undefined;
7648findLast<T>(fn: (x: T) => boolean): (list: readonly T[]) => T | undefined;
7649```
7650
7651</details>
7652
7653<details>
7654
7655<summary><strong>R.findLast</strong> source</summary>
7656
7657```javascript
7658export function findLast(predicate, list){
7659 if (arguments.length === 1) return _list => findLast(predicate, _list)
7660
7661 let index = list.length
7662
7663 while (--index >= 0){
7664 if (predicate(list[ index ])){
7665 return list[ index ]
7666 }
7667 }
7668
7669 return undefined
7670}
7671```
7672
7673</details>
7674
7675<details>
7676
7677<summary><strong>Tests</strong></summary>
7678
7679```javascript
7680import { findLast } from './findLast'
7681
7682test('happy', () => {
7683 const result = findLast(x => {
7684 return x > 1
7685 },
7686 [ 1, 1, 1, 2, 3, 4, 1 ]
7687 )
7688 expect(result).toEqual(4)
7689
7690 expect(findLast(x => x === 0, [ 0, 1, 1, 2, 3, 4, 1 ])).toEqual(0)
7691})
7692
7693test('with curry', () => {
7694 expect(findLast(x => x > 1)([ 1, 1, 1, 2, 3, 4, 1 ])).toEqual(4)
7695})
7696
7697const obj1 = { x : 100 }
7698const obj2 = { x : 200 }
7699const a = [ 11, 10, 9, 'cow', obj1, 8, 7, 100, 200, 300, obj2, 4, 3, 2, 1, 0 ]
7700const even = function (x){
7701 return x % 2 === 0
7702}
7703const gt100 = function (x){
7704 return x > 100
7705}
7706const isStr = function (x){
7707 return typeof x === 'string'
7708}
7709const xGt100 = function (o){
7710 return o && o.x > 100
7711}
7712
7713test('ramda 1', () => {
7714 expect(findLast(even, a)).toEqual(0)
7715 expect(findLast(gt100, a)).toEqual(300)
7716 expect(findLast(isStr, a)).toEqual('cow')
7717 expect(findLast(xGt100, a)).toEqual(obj2)
7718})
7719
7720test('ramda 2', () => {
7721 expect(findLast(even, [ 'zing' ])).toEqual(undefined)
7722})
7723
7724test('ramda 3', () => {
7725 expect(findLast(even, [ 2, 3, 5 ])).toEqual(2)
7726})
7727
7728test('ramda 4', () => {
7729 expect(findLast(even, [])).toEqual(undefined)
7730})
7731```
7732
7733</details>
7734
7735<details>
7736
7737<summary><strong>Typescript</strong> test</summary>
7738
7739```typescript
7740import {findLast} from 'rambda'
7741
7742const list = [1, 2, 3]
7743
7744describe('R.findLast', () => {
7745 it('happy', () => {
7746 const predicate = (x: number) => x > 2
7747 const result = findLast(predicate, list)
7748 result // $ExpectType number | undefined
7749 })
7750 it('curried', () => {
7751 const predicate = (x: number) => x > 2
7752 const result = findLast(predicate)(list)
7753 result // $ExpectType number | undefined
7754 })
7755})
7756```
7757
7758</details>
7759
7760[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#findLast)
7761
7762### findLastIndex
7763
7764```typescript
7765
7766findLastIndex<T>(predicate: (x: T) => boolean, list: readonly T[]): number
7767```
7768
7769It returns the index of the last element of `list` satisfying the `predicate` function.
7770
7771If there is no such element, then `-1` is returned.
7772
7773```javascript
7774const predicate = x => R.type(x.foo) === 'Number'
7775const list = [{foo: 0}, {foo: 1}]
7776
7777const result = R.findLastIndex(predicate, list)
7778// => 1
7779```
7780
7781<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20predicate%20%3D%20x%20%3D%3E%20R.type(x.foo)%20%3D%3D%3D%20'Number'%0Aconst%20list%20%3D%20%5B%7Bfoo%3A%200%7D%2C%20%7Bfoo%3A%201%7D%5D%0A%0Aconst%20result%20%3D%20R.findLastIndex(predicate%2C%20list)%0A%2F%2F%20%3D%3E%201">Try this <strong>R.findLastIndex</strong> example in Rambda REPL</a>
7782
7783<details>
7784
7785<summary>All Typescript definitions</summary>
7786
7787```typescript
7788findLastIndex<T>(predicate: (x: T) => boolean, list: readonly T[]): number;
7789findLastIndex<T>(predicate: (x: T) => boolean): (list: readonly T[]) => number;
7790```
7791
7792</details>
7793
7794<details>
7795
7796<summary><strong>R.findLastIndex</strong> source</summary>
7797
7798```javascript
7799export function findLastIndex(fn, list){
7800 if (arguments.length === 1) return _list => findLastIndex(fn, _list)
7801
7802 let index = list.length
7803
7804 while (--index >= 0){
7805 if (fn(list[ index ])){
7806 return index
7807 }
7808 }
7809
7810 return -1
7811}
7812```
7813
7814</details>
7815
7816<details>
7817
7818<summary><strong>Tests</strong></summary>
7819
7820```javascript
7821import { findLastIndex } from './findLastIndex'
7822
7823test('happy', () => {
7824 const result = findLastIndex((x) => {
7825
7826 return x > 1
7827 },
7828 [ 1, 1, 1, 2, 3, 4, 1 ])
7829
7830 expect(result).toEqual(5)
7831
7832 expect(findLastIndex(x => x === 0, [ 0, 1, 1, 2, 3, 4, 1 ])).toEqual(0)
7833})
7834
7835test('with curry', () => {
7836 expect(findLastIndex(x => x > 1)([ 1, 1, 1, 2, 3, 4, 1 ])).toEqual(5)
7837})
7838
7839const obj1 = { x : 100 }
7840const obj2 = { x : 200 }
7841const a = [ 11, 10, 9, 'cow', obj1, 8, 7, 100, 200, 300, obj2, 4, 3, 2, 1, 0 ]
7842const even = function (x){
7843 return x % 2 === 0
7844}
7845const gt100 = function (x){
7846 return x > 100
7847}
7848const isStr = function (x){
7849 return typeof x === 'string'
7850}
7851const xGt100 = function (o){
7852 return o && o.x > 100
7853}
7854
7855test('ramda 1', () => {
7856 expect(findLastIndex(even, a)).toEqual(15)
7857 expect(findLastIndex(gt100, a)).toEqual(9)
7858 expect(findLastIndex(isStr, a)).toEqual(3)
7859 expect(findLastIndex(xGt100, a)).toEqual(10)
7860})
7861
7862test('ramda 2', () => {
7863 expect(findLastIndex(even, [ 'zing' ])).toEqual(-1)
7864})
7865
7866test('ramda 3', () => {
7867 expect(findLastIndex(even, [ 2, 3, 5 ])).toEqual(0)
7868})
7869
7870test('ramda 4', () => {
7871 expect(findLastIndex(even, [])).toEqual(-1)
7872})
7873```
7874
7875</details>
7876
7877<details>
7878
7879<summary><strong>Typescript</strong> test</summary>
7880
7881```typescript
7882import {findLastIndex} from 'rambda'
7883
7884const list = [1, 2, 3]
7885
7886describe('R.findLastIndex', () => {
7887 it('happy', () => {
7888 const predicate = (x: number) => x > 2
7889 const result = findLastIndex(predicate, list)
7890 result // $ExpectType number
7891 })
7892 it('curried', () => {
7893 const predicate = (x: number) => x > 2
7894 const result = findLastIndex(predicate)(list)
7895 result // $ExpectType number
7896 })
7897})
7898```
7899
7900</details>
7901
7902[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#findLastIndex)
7903
7904### flatten
7905
7906```typescript
7907
7908flatten<T>(list: readonly any[]): T[]
7909```
7910
7911It deeply flattens an array.
7912
7913```javascript
7914const result = R.flatten([
7915 1,
7916 2,
7917 [3, 30, [300]],
7918 [4]
7919])
7920// => [ 1, 2, 3, 30, 300, 4 ]
7921```
7922
7923<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.flatten(%5B%0A%20%201%2C%20%0A%20%202%2C%20%0A%20%20%5B3%2C%2030%2C%20%5B300%5D%5D%2C%20%0A%20%20%5B4%5D%0A%5D)%0A%2F%2F%20%3D%3E%20%5B%201%2C%202%2C%203%2C%2030%2C%20300%2C%204%20%5D">Try this <strong>R.flatten</strong> example in Rambda REPL</a>
7924
7925<details>
7926
7927<summary>All Typescript definitions</summary>
7928
7929```typescript
7930flatten<T>(list: readonly any[]): T[];
7931```
7932
7933</details>
7934
7935<details>
7936
7937<summary><strong>R.flatten</strong> source</summary>
7938
7939```javascript
7940import { _isArray } from './_internals/_isArray'
7941
7942export function flatten(list, input){
7943 const willReturn = input === undefined ? [] : input
7944
7945 for (let i = 0; i < list.length; i++){
7946 if (_isArray(list[ i ])){
7947 flatten(list[ i ], willReturn)
7948 } else {
7949 willReturn.push(list[ i ])
7950 }
7951 }
7952
7953 return willReturn
7954}
7955```
7956
7957</details>
7958
7959<details>
7960
7961<summary><strong>Tests</strong></summary>
7962
7963```javascript
7964import { flatten } from './flatten'
7965
7966test('happy', () => {
7967 expect(flatten([ 1, 2, 3, [ [ [ [ [ 4 ] ] ] ] ] ])).toEqual([ 1, 2, 3, 4 ])
7968
7969 expect(flatten([ 1, [ 2, [ [ 3 ] ] ], [ 4 ] ])).toEqual([ 1, 2, 3, 4 ])
7970
7971 expect(flatten([ 1, [ 2, [ [ [ 3 ] ] ] ], [ 4 ] ])).toEqual([ 1, 2, 3, 4 ])
7972
7973 expect(flatten([ 1, 2, [ 3, 4 ], 5, [ 6, [ 7, 8, [ 9, [ 10, 11 ], 12 ] ] ] ])).toEqual([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ])
7974})
7975
7976test('readme example', () => {
7977 const result = flatten([ 1, 2, [ 3, 30, [ 300 ] ], [ 4 ] ])
7978 expect(result).toEqual([ 1, 2, 3, 30, 300, 4 ])
7979})
7980```
7981
7982</details>
7983
7984<details>
7985
7986<summary><strong>Typescript</strong> test</summary>
7987
7988```typescript
7989import {flatten} from 'rambda'
7990
7991describe('flatten', () => {
7992 it('happy', () => {
7993 const result = flatten<number>([1, 2, [3, [4]]])
7994 result // $ExpectType number[]
7995 })
7996})
7997```
7998
7999</details>
8000
8001[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#flatten)
8002
8003### flip
8004
8005```typescript
8006
8007flip<T, U, TResult>(fn: (arg0: T, arg1: U) => TResult): (arg1: U, arg0?: T) => TResult
8008```
8009
8010It returns function which calls `fn` with exchanged first and second argument.
8011
8012> :boom: Rambda's **flip** will throw if the arity of the input function is greater or equal to 5.
8013
8014```javascript
8015const subtractFlip = R.flip(R.subtract)
8016
8017const result = [
8018 subtractFlip(1,7),
8019 R.flip(1, 6)
8020]
8021// => [6, -6]
8022```
8023
8024<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20subtractFlip%20%3D%20R.flip(R.subtract)%0A%0Aconst%20result%20%3D%20%5B%0A%20%20subtractFlip(1%2C7)%2C%0A%20%20R.flip(1%2C%206)%0A%5D%20%20%0A%2F%2F%20%3D%3E%20%5B6%2C%20-6%5D">Try this <strong>R.flip</strong> example in Rambda REPL</a>
8025
8026<details>
8027
8028<summary>All Typescript definitions</summary>
8029
8030```typescript
8031flip<T, U, TResult>(fn: (arg0: T, arg1: U) => TResult): (arg1: U, arg0?: T) => TResult;
8032flip<F extends (...args: any) => any, P extends FunctionToolbelt.Parameters<F>>(fn: F): FunctionToolbelt.Curry<(...args: ListToolbelt.Merge<[P[1], P[0]], P>) => FunctionToolbelt.Return<F>>;
8033```
8034
8035</details>
8036
8037<details>
8038
8039<summary><strong>R.flip</strong> source</summary>
8040
8041```javascript
8042function flipFn(fn){
8043 return (...input) => {
8044 if (input.length === 1){
8045 return holder => fn(holder, input[ 0 ])
8046 } else if (input.length === 2){
8047 return fn(input[ 1 ], input[ 0 ])
8048 } else if (input.length === 3){
8049 return fn(
8050 input[ 1 ], input[ 0 ], input[ 2 ]
8051 )
8052 } else if (input.length === 4){
8053 return fn(
8054 input[ 1 ], input[ 0 ], input[ 2 ], input[ 3 ]
8055 )
8056 }
8057
8058 throw new Error('R.flip doesn\'t work with arity > 4')
8059 }
8060}
8061
8062export function flip(fn){
8063 return flipFn(fn)
8064}
8065```
8066
8067</details>
8068
8069<details>
8070
8071<summary><strong>Tests</strong></summary>
8072
8073```javascript
8074import { flip } from './flip'
8075import { subtract } from './subtract'
8076import { update } from './update'
8077
8078test('function with arity of 2', () => {
8079 const subtractFlipped = flip(subtract)
8080
8081 expect(subtractFlipped(1)(7)).toEqual(6)
8082 expect(subtractFlipped(1, 7)).toEqual(6)
8083 expect(subtractFlipped(
8084 1, 7, 9
8085 )).toEqual(6)
8086})
8087
8088test('function with arity of 3', () => {
8089 const updateFlipped = flip(update)
8090
8091 const result = updateFlipped(
8092 88, 0, [ 1, 2, 3 ]
8093 )
8094 const curriedResult = updateFlipped(88, 0)([ 1, 2, 3 ])
8095 const tripleCurriedResult = updateFlipped(88)(0)([ 1, 2, 3 ])
8096 expect(result).toEqual([ 88, 2, 3 ])
8097 expect(curriedResult).toEqual([ 88, 2, 3 ])
8098 expect(tripleCurriedResult).toEqual([ 88, 2, 3 ])
8099})
8100
8101test('function with arity of 4', () => {
8102 const testFunction = (
8103 a, b, c, d
8104 ) => `${ a - b }==${ c - d }`
8105 const testFunctionFlipped = flip(testFunction)
8106
8107 const result = testFunction(
8108 1, 2, 3, 4
8109 )
8110 const flippedResult = testFunctionFlipped(
8111 2, 1, 3, 4
8112 )
8113 expect(result).toEqual(flippedResult)
8114 expect(result).toEqual('-1==-1')
8115})
8116
8117test('function with arity of 5', () => {
8118 const testFunction = (
8119 a, b, c, d, e
8120 ) => `${ a - b }==${ c - d - e }`
8121 const testFunctionFlipped = flip(testFunction)
8122
8123 expect(() => testFunctionFlipped(
8124 1, 2, 3, 4, 5
8125 )).toThrowWithMessage(Error,
8126 'R.flip doesn\'t work with arity > 4')
8127})
8128```
8129
8130</details>
8131
8132<details>
8133
8134<summary><strong>Typescript</strong> test</summary>
8135
8136```typescript
8137import * as R from 'ramda'
8138import {flip, subtract} from 'rambda'
8139
8140describe('R.flip', () => {
8141 it('function with arity of 2', () => {
8142 const subtractFlipped = flip(subtract)
8143 const result = subtractFlipped(1, 7)
8144 const curriedResult = subtractFlipped(1)(7)
8145 curriedResult // $ExpectType number
8146
8147 // This is wrong
8148 // ============================================
8149 result // $ExpectType (y: number) => number
8150 })
8151
8152 it('function with arity of 3', () => {
8153 function testFunction(a: number, b: string, c: number): string {
8154 return `${b}==${a + c}`
8155 }
8156 const flippedTestFunction = flip(testFunction)
8157
8158 const result = flippedTestFunction('foo', 1, 2)
8159 result // $ExpectType string
8160 })
8161})
8162
8163describe('Ramda.flip', () => {
8164 it('function with arity of 2', () => {
8165 const subtractFlipped = R.flip(R.subtract)
8166 const result = subtractFlipped(1, 7)
8167 const curriedResult = subtractFlipped(1)(7)
8168 curriedResult // $ExpectType number
8169
8170 // This is wrong
8171 // ============================================
8172 result // $ExpectType (b: number) => number
8173 })
8174})
8175```
8176
8177</details>
8178
8179<details>
8180
8181<summary>4 failed <italic>Ramda.flip</italic> specs
8182
8183> :boom: Reason for the failure: Ramda.flip returns a curried function | Rambda.flip work only for functions with arity below 5
8184</summary>
8185
8186```javascript
8187var jsv = require('jsverify');
8188
8189var R = require('../../../../dist/rambda.js');
8190var eq = require('./shared/eq');
8191var funcN = require('./shared/funcN');
8192describe('flip', function() {
8193 it('returns a function which inverts the first two arguments to the supplied function', function() {
8194 var f = function(a, b, c) {return a + ' ' + b + ' ' + c;};
8195 var g = R.flip(f);
8196 eq(f('a', 'b', 'c'), 'a b c');
8197 eq(g('a', 'b', 'c'), 'b a c');
8198 });
8199 it('returns a curried function', function() {
8200 var f = function(a, b, c) {return a + ' ' + b + ' ' + c;};
8201 var g = R.flip(f)('a');
8202 eq(g('b', 'c'), 'b a c');
8203 });
8204 it('returns a function with the correct arity', function() {
8205 var f2 = function(a, b) {return a + ' ' + b;};
8206 var f3 = function(a, b, c) {return a + ' ' + b + ' ' + c;};
8207 eq(R.flip(f2).length, 2);
8208 eq(R.flip(f3).length, 3);
8209 });
8210});
8211describe('flip properties', function() {
8212 jsv.property('inverts first two arguments', funcN(3), jsv.json, jsv.json, jsv.json, function(f, a, b, c) {
8213 var g = R.flip(f);
8214 return R.equals(f(a, b, c), g(b, a, c));
8215 });
8216});
8217```
8218
8219</details>
8220
8221[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#flip)
8222
8223### forEach
8224
8225```typescript
8226
8227forEach<T>(fn: MapFunctionArray<T, void>, list: readonly T[]): T[]
8228```
8229
8230It applies `iterable` function over all members of `list` and returns `list`.
8231
8232> :boom: It works with objects, unlike `Ramda`.
8233
8234```javascript
8235const sideEffect = {}
8236const result = R.forEach(
8237 x => sideEffect[`foo${x}`] = x
8238)([1, 2])
8239
8240sideEffect //=> {foo1: 1, foo2: 2}
8241result //=> [1, 2]
8242```
8243
8244<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20sideEffect%20%3D%20%7B%7D%0Aconst%20result%20%3D%20R.forEach(%0A%20%20x%20%3D%3E%20sideEffect%5B%60foo%24%7Bx%7D%60%5D%20%3D%20x%0A)(%5B1%2C%202%5D)%0A%0AsideEffect%20%2F%2F%3D%3E%20%7Bfoo1%3A%201%2C%20foo2%3A%202%7D%0Aresult%20%2F%2F%3D%3E%20%5B1%2C%202%5D">Try this <strong>R.forEach</strong> example in Rambda REPL</a>
8245
8246<details>
8247
8248<summary>All Typescript definitions</summary>
8249
8250```typescript
8251forEach<T>(fn: MapFunctionArray<T, void>, list: readonly T[]): T[];
8252forEach<T>(fn: MapFunctionArray<T, void>): (list: readonly T[]) => T[];
8253forEach<T>(fn: MapFunctionObject<T, void>, list: Dictionary<T>): Dictionary<T>;
8254forEach<T, U>(fn: MapFunctionObject<T, void>): (list: Dictionary<T>) => Dictionary<T>;
8255```
8256
8257</details>
8258
8259<details>
8260
8261<summary><strong>R.forEach</strong> source</summary>
8262
8263```javascript
8264import { _isArray } from './_internals/_isArray'
8265import { _keys } from './_internals/_keys'
8266
8267export function forEach(fn, list){
8268 if (arguments.length === 1) return _list => forEach(fn, _list)
8269
8270 if (list === undefined){
8271 return
8272 }
8273
8274 if (_isArray(list)){
8275 let index = 0
8276 const len = list.length
8277
8278 while (index < len){
8279 fn(list[ index ])
8280 index++
8281 }
8282 } else {
8283 let index = 0
8284 const keys = _keys(list)
8285 const len = keys.length
8286
8287 while (index < len){
8288 const key = keys[ index ]
8289 fn(
8290 list[ key ], key, list
8291 )
8292 index++
8293 }
8294 }
8295
8296 return list
8297}
8298```
8299
8300</details>
8301
8302<details>
8303
8304<summary><strong>Tests</strong></summary>
8305
8306```javascript
8307import { forEach } from './forEach'
8308import { type } from './type'
8309
8310test('iterate over object', () => {
8311 const obj = {
8312 a : 1,
8313 b : [ 1, 2 ],
8314 c : { d : 7 },
8315 f : 'foo',
8316 }
8317 const result = {}
8318 const returned = forEach((
8319 val, prop, inputObj
8320 ) => {
8321 expect(type(inputObj)).toBe('Object')
8322 result[ prop ] = `${ prop }-${ type(val) }`
8323 })(obj)
8324
8325 const expected = {
8326 a : 'a-Number',
8327 b : 'b-Array',
8328 c : 'c-Object',
8329 f : 'f-String',
8330 }
8331
8332 expect(result).toEqual(expected)
8333 expect(returned).toEqual(obj)
8334})
8335
8336test('happy', () => {
8337 const sideEffect = {}
8338 forEach(x => sideEffect[ `foo${ x }` ] = x + 10)([ 1, 2 ])
8339
8340 expect(sideEffect).toEqual({
8341 foo1 : 11,
8342 foo2 : 12,
8343 })
8344})
8345
8346test('with empty list', () => {
8347 const list = []
8348 const result = forEach(x => x * x)(list)
8349
8350 expect(result).toEqual(list)
8351})
8352
8353test('with wrong input', () => {
8354 const list = undefined
8355 const result = forEach(x => x * x)(list)
8356
8357 expect(result).toBeUndefined()
8358})
8359
8360test('returns the input', () => {
8361 const list = [ 1, 2, 3 ]
8362 const result = forEach(x => x * x)(list)
8363
8364 expect(result).toEqual(list)
8365})
8366```
8367
8368</details>
8369
8370<details>
8371
8372<summary><strong>Typescript</strong> test</summary>
8373
8374```typescript
8375import {forEach} from 'rambda'
8376
8377const list = [1, 2, 3]
8378const obj = {a: 1, b: 2}
8379
8380describe('R.forEach with arrays', () => {
8381 it('happy', () => {
8382 const result = forEach(a => {
8383 a // $ExpectType number
8384 }, list)
8385 result // $ExpectType number[]
8386 })
8387 it('curried require an explicit typing', () => {
8388 const result = forEach<number>(a => {
8389 a // $ExpectType number
8390 })(list)
8391 result // $ExpectType number[]
8392 })
8393})
8394
8395describe('R.forEach with objects', () => {
8396 it('happy', () => {
8397 const result = forEach((a, b, c) => {
8398 a // $ExpectType number
8399 b // $ExpectType string
8400 c // $ExpectType Dictionary<number>
8401 return `${a}`
8402 }, obj)
8403 result // $ExpectType Dictionary<number>
8404 })
8405 it('curried require an input typing and a dummy third typing', () => {
8406 // Required in order all typings to work
8407 const result = forEach<number, any>((a, b, c) => {
8408 a // $ExpectType number
8409 b // $ExpectType string
8410 c // $ExpectType Dictionary<number>
8411 })(obj)
8412 result // $ExpectType Dictionary<number>
8413 })
8414 it('iterator without property', () => {
8415 const result = forEach(a => {
8416 a // $ExpectType number
8417 }, obj)
8418 result // $ExpectType Dictionary<number>
8419 })
8420})
8421```
8422
8423</details>
8424
8425<details>
8426
8427<summary>1 failed <italic>Ramda.forEach</italic> specs
8428
8429> :boom: Reason for the failure: Ramda method dispatches to `forEach` method
8430</summary>
8431
8432```javascript
8433var R = require('../../../../dist/rambda.js');
8434var eq = require('./shared/eq');
8435
8436describe('forEach', function() {
8437 var list = [{x: 1, y: 2}, {x: 100, y: 200}, {x: 300, y: 400}, {x: 234, y: 345}];
8438 it('dispatches to `forEach` method', function() {
8439 var dispatched = false;
8440 var fn = function() {};
8441 function DummyList() {}
8442 DummyList.prototype.forEach = function(callback) {
8443 dispatched = true;
8444 eq(callback, fn);
8445 };
8446 R.forEach(fn, new DummyList());
8447 eq(dispatched, true);
8448 });
8449});
8450```
8451
8452</details>
8453
8454[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#forEach)
8455
8456### fromPairs
8457
8458```typescript
8459
8460fromPairs<V>(listOfPairs: KeyValuePair<string, V>[]): { [index: string]: V }
8461```
8462
8463It transforms a `listOfPairs` to an object.
8464
8465```javascript
8466const listOfPairs = [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', [ 3, 4 ] ] ]
8467const expected = {
8468 a : 1,
8469 b : 2,
8470 c : [ 3, 4 ],
8471}
8472
8473const result = R.fromPairs(listOfPairs)
8474// => `result` is equal to `expected`
8475```
8476
8477<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20listOfPairs%20%3D%20%5B%20%5B%20'a'%2C%201%20%5D%2C%20%5B%20'b'%2C%202%20%5D%2C%20%5B%20'c'%2C%20%5B%203%2C%204%20%5D%20%5D%20%5D%0Aconst%20expected%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%202%2C%0A%20%20c%20%3A%20%5B%203%2C%204%20%5D%2C%0A%7D%0A%0Aconst%20result%20%3D%20R.fromPairs(listOfPairs)%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.fromPairs</strong> example in Rambda REPL</a>
8478
8479<details>
8480
8481<summary>All Typescript definitions</summary>
8482
8483```typescript
8484fromPairs<V>(listOfPairs: KeyValuePair<string, V>[]): { [index: string]: V };
8485fromPairs<V>(listOfPairs: KeyValuePair<number, V>[]): { [index: number]: V };
8486```
8487
8488</details>
8489
8490<details>
8491
8492<summary><strong>R.fromPairs</strong> source</summary>
8493
8494```javascript
8495export function fromPairs(listOfPairs){
8496 const toReturn = {}
8497 listOfPairs.forEach(([ prop, value ]) => toReturn[ prop ] = value)
8498
8499 return toReturn
8500}
8501```
8502
8503</details>
8504
8505<details>
8506
8507<summary><strong>Tests</strong></summary>
8508
8509```javascript
8510import { fromPairs } from './fromPairs'
8511
8512const list = [
8513 [ 'a', 1 ],
8514 [ 'b', 2 ],
8515 [ 'c', [ 3, 4 ] ],
8516]
8517const expected = {
8518 a : 1,
8519 b : 2,
8520 c : [ 3, 4 ],
8521}
8522
8523test('happy', () => {
8524 expect(fromPairs(list)).toEqual(expected)
8525})
8526```
8527
8528</details>
8529
8530<details>
8531
8532<summary><strong>Typescript</strong> test</summary>
8533
8534```typescript
8535import {fromPairs} from 'rambda'
8536
8537describe('R.fromPairs - require explicit type for input list', () => {
8538 it('with string index', () => {
8539 const list: [string, number][] = [
8540 ['a', 1],
8541 ['b', 2],
8542 ['c', 3],
8543 ]
8544 const result = fromPairs(list)
8545
8546 result // $ExpectType { [index: string]: number; }
8547 })
8548 it('with number index', () => {
8549 const list: [number, string][] = [
8550 [10, 'foo'],
8551 [20, 'bar'],
8552 [30, 'baz'],
8553 ]
8554 const result = fromPairs(list)
8555
8556 result // $ExpectType { [index: number]: string; }
8557 })
8558})
8559```
8560
8561</details>
8562
8563[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#fromPairs)
8564
8565### groupBy
8566
8567```typescript
8568
8569groupBy<T>(groupFn: (x: T) => string, list: readonly T[]): { [index: string]: T[] }
8570```
8571
8572It splits `list` according to a provided `groupFn` function and returns an object.
8573
8574```javascript
8575const list = [ 'a', 'b', 'aa', 'bb' ]
8576const groupFn = x => x.length
8577
8578const result = R.groupBy(groupFn, list)
8579// => { '1': ['a', 'b'], '2': ['aa', 'bb'] }
8580```
8581
8582<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%20'a'%2C%20'b'%2C%20'aa'%2C%20'bb'%20%5D%0Aconst%20groupFn%20%3D%20x%20%3D%3E%20x.length%0A%0Aconst%20result%20%3D%20R.groupBy(groupFn%2C%20list)%0A%2F%2F%20%3D%3E%20%7B%20'1'%3A%20%5B'a'%2C%20'b'%5D%2C%20'2'%3A%20%5B'aa'%2C%20'bb'%5D%20%7D">Try this <strong>R.groupBy</strong> example in Rambda REPL</a>
8583
8584<details>
8585
8586<summary>All Typescript definitions</summary>
8587
8588```typescript
8589groupBy<T>(groupFn: (x: T) => string, list: readonly T[]): { [index: string]: T[] };
8590groupBy<T>(groupFn: (x: T) => string): (list: readonly T[]) => { [index: string]: T[] };
8591```
8592
8593</details>
8594
8595<details>
8596
8597<summary><strong>R.groupBy</strong> source</summary>
8598
8599```javascript
8600export function groupBy(groupFn, list){
8601 if (arguments.length === 1) return _list => groupBy(groupFn, _list)
8602
8603 const result = {}
8604 for (let i = 0; i < list.length; i++){
8605 const item = list[ i ]
8606 const key = groupFn(item)
8607
8608 if (!result[ key ]){
8609 result[ key ] = []
8610 }
8611
8612 result[ key ].push(item)
8613 }
8614
8615 return result
8616}
8617```
8618
8619</details>
8620
8621<details>
8622
8623<summary><strong>Tests</strong></summary>
8624
8625```javascript
8626import { groupBy } from './groupBy'
8627import { prop } from './prop'
8628
8629test('groupBy', () => {
8630 const list = [
8631 {
8632 age : 12,
8633 name : 'john',
8634 },
8635 {
8636 age : 12,
8637 name : 'jack',
8638 },
8639 {
8640 age : 24,
8641 name : 'mary',
8642 },
8643 {
8644 age : 24,
8645 name : 'steve',
8646 },
8647 ]
8648 const expectedResult = {
8649 12 : [
8650 {
8651 age : 12,
8652 name : 'john',
8653 },
8654 {
8655 age : 12,
8656 name : 'jack',
8657 },
8658 ],
8659 24 : [
8660 {
8661 age : 24,
8662 name : 'mary',
8663 },
8664 {
8665 age : 24,
8666 name : 'steve',
8667 },
8668 ],
8669 }
8670
8671 expect(groupBy(prop('age'))(list)).toEqual(expectedResult)
8672 expect(groupBy(prop('age'), list)).toEqual(expectedResult)
8673})
8674```
8675
8676</details>
8677
8678<details>
8679
8680<summary><strong>Typescript</strong> test</summary>
8681
8682```typescript
8683import {groupBy} from 'rambda'
8684
8685describe('R.groupBy', () => {
8686 it('happy', () => {
8687 const groupByFn = (x: string) => String(x.length)
8688 const list = ['foo', 'barr', 'bazzz']
8689
8690 const result = groupBy(groupByFn, list)
8691 result // $ExpectType { [index: string]: string[]; }
8692
8693 const curriedResult = groupBy(groupByFn)(list)
8694 curriedResult // $ExpectType { [index: string]: string[]; }
8695 })
8696})
8697```
8698
8699</details>
8700
8701<details>
8702
8703<summary>1 failed <italic>Ramda.groupBy</italic> specs
8704
8705> :boom: Reason for the failure: Ramda method support transforms
8706</summary>
8707
8708```javascript
8709var R = require('../../../../dist/rambda.js');
8710var eq = require('./shared/eq');
8711var _isTransformer = require('rambda/internal/_isTransformer');
8712
8713describe('groupBy', function() {
8714 it('dispatches on transformer objects in list position', function() {
8715 var byType = R.prop('type');
8716 var xf = {
8717 '@@transducer/init': function() { return {}; },
8718 '@@transducer/result': function(x) { return x; },
8719 '@@transducer/step': R.mergeRight
8720 };
8721 eq(_isTransformer(R.groupBy(byType, xf)), true);
8722 });
8723});
8724```
8725
8726</details>
8727
8728[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#groupBy)
8729
8730### groupWith
8731
8732```typescript
8733
8734groupWith<T>(compareFn: (x: T, y: T) => boolean): (input: readonly T[]) => T[][]
8735```
8736
8737It returns separated version of list or string `input`, where separation is done with equality `compareFn` function.
8738
8739```javascript
8740const compareFn = (x, y) => x === y
8741const list = [1, 2, 2, 1, 1, 2]
8742
8743const result = R.groupWith(isConsecutive, list)
8744// => [[1], [2,2], [1,1], [2]]
8745```
8746
8747<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20compareFn%20%3D%20(x%2C%20y)%20%3D%3E%20x%20%3D%3D%3D%20y%0Aconst%20list%20%3D%20%5B1%2C%202%2C%202%2C%201%2C%201%2C%202%5D%0A%0Aconst%20result%20%3D%20R.groupWith(isConsecutive%2C%20list)%0A%2F%2F%20%3D%3E%20%5B%5B1%5D%2C%20%5B2%2C2%5D%2C%20%5B1%2C1%5D%2C%20%5B2%5D%5D">Try this <strong>R.groupWith</strong> example in Rambda REPL</a>
8748
8749<details>
8750
8751<summary>All Typescript definitions</summary>
8752
8753```typescript
8754groupWith<T>(compareFn: (x: T, y: T) => boolean): (input: readonly T[]) => T[][];
8755groupWith<T>(compareFn: (x: T, y: T) => boolean, input: readonly T[]): T[][];
8756groupWith<T>(compareFn: (x: T, y: T) => boolean, input: string): string[];
8757```
8758
8759</details>
8760
8761<details>
8762
8763<summary><strong>R.groupWith</strong> source</summary>
8764
8765```javascript
8766import { _isArray } from './_internals/_isArray'
8767
8768export function groupWith(compareFn, list){
8769 if (!_isArray(list)) throw new TypeError('list.reduce is not a function')
8770
8771 const clone = list.slice()
8772
8773 if (list.length === 1) return [ clone ]
8774
8775 const toReturn = []
8776 let holder = []
8777
8778 clone.reduce((
8779 prev, current, i
8780 ) => {
8781 if (i === 0) return current
8782
8783 const okCompare = compareFn(prev, current)
8784 const holderIsEmpty = holder.length === 0
8785 const lastCall = i === list.length - 1
8786
8787 if (okCompare){
8788 if (holderIsEmpty) holder.push(prev)
8789 holder.push(current)
8790 if (lastCall) toReturn.push(holder)
8791
8792 return current
8793 }
8794
8795 if (holderIsEmpty){
8796 toReturn.push([ prev ])
8797 if (lastCall) toReturn.push([ current ])
8798
8799 return current
8800 }
8801
8802 toReturn.push(holder)
8803 if (lastCall) toReturn.push([ current ])
8804 holder = []
8805
8806 return current
8807 }, undefined)
8808
8809 return toReturn
8810}
8811```
8812
8813</details>
8814
8815<details>
8816
8817<summary><strong>Tests</strong></summary>
8818
8819```javascript
8820import { equals } from './equals'
8821import { groupWith } from './groupWith'
8822
8823test('issue is fixed', () => {
8824 const result = groupWith(equals, [ 1, 2, 2, 3 ])
8825 const expected = [ [ 1 ], [ 2, 2 ], [ 3 ] ]
8826 expect(result).toEqual(expected)
8827})
8828
8829test('long list', () => {
8830 const result = groupWith(equals, [
8831 0,
8832 1,
8833 1,
8834 2,
8835 3,
8836 5,
8837 8,
8838 13,
8839 21,
8840 21,
8841 21,
8842 1,
8843 2,
8844 ])
8845
8846 const expected = [
8847 [ 0 ],
8848 [ 1, 1 ],
8849 [ 2 ],
8850 [ 3 ],
8851 [ 5 ],
8852 [ 8 ],
8853 [ 13 ],
8854 [ 21, 21, 21 ],
8855 [ 1 ],
8856 [ 2 ],
8857 ]
8858 expect(result).toEqual(expected)
8859})
8860
8861test('readme example', () => {
8862 const list = [ 4, 3, 6, 2, 2, 1 ]
8863
8864 const result = groupWith((a, b) => a - b === 1, list)
8865 const expected = [ [ 4, 3 ], [ 6 ], [ 2 ], [ 2, 1 ] ]
8866 expect(result).toEqual(expected)
8867})
8868
8869test('throw with string as input', () => {
8870 expect(() => groupWith(equals, 'Mississippi')).toThrowWithMessage(TypeError,
8871 'list.reduce is not a function')
8872})
8873
8874const isConsecutive = function (a, b){
8875 return a + 1 === b
8876}
8877
8878test('fix coverage', () => {
8879 expect(groupWith(isConsecutive, [ 1, 2, 3, 0 ])).toEqual([ [ 1, 2, 3 ], [ 0 ] ])
8880})
8881
8882test('from ramda 0', () => {
8883 expect(groupWith(equals, [])).toEqual([])
8884 expect(groupWith(isConsecutive, [])).toEqual([])
8885})
8886
8887test('from ramda 1', () => {
8888 expect(groupWith(isConsecutive, [ 4, 3, 2, 1 ])).toEqual([
8889 [ 4 ],
8890 [ 3 ],
8891 [ 2 ],
8892 [ 1 ],
8893 ])
8894})
8895
8896test('from ramda 2', () => {
8897 expect(groupWith(isConsecutive, [ 1, 2, 3, 4 ])).toEqual([ [ 1, 2, 3, 4 ] ])
8898})
8899
8900test('from ramda 3', () => {
8901 expect(groupWith(isConsecutive, [ 1, 2, 2, 3 ])).toEqual([
8902 [ 1, 2 ],
8903 [ 2, 3 ],
8904 ])
8905 expect(groupWith(isConsecutive, [ 1, 2, 9, 3, 4 ])).toEqual([
8906 [ 1, 2 ],
8907 [ 9 ],
8908 [ 3, 4 ],
8909 ])
8910})
8911
8912test('list with single item', () => {
8913 const result = groupWith(equals, [ 0 ])
8914
8915 const expected = [ [ 0 ] ]
8916 expect(result).toEqual(expected)
8917})
8918```
8919
8920</details>
8921
8922<details>
8923
8924<summary><strong>Typescript</strong> test</summary>
8925
8926```typescript
8927import {groupWith} from 'rambda'
8928
8929describe('R.groupWith', () => {
8930 it('happy', () => {
8931 const groupWithFn = (x: string, y: string) => x.length === y.length
8932 const list = ['foo', 'bar', 'bazzz']
8933
8934 const result = groupWith(groupWithFn, list)
8935 const curriedResult = groupWith(groupWithFn)(list)
8936 result // $ExpectType string[][]
8937 curriedResult // $ExpectType string[][]
8938 })
8939})
8940```
8941
8942</details>
8943
8944<details>
8945
8946<summary>2 failed <italic>Ramda.groupWith</italic> specs
8947
8948> :boom: Reason for the failure: Ramda method support string
8949</summary>
8950
8951```javascript
8952var R = require('../../../../dist/rambda.js');
8953var eq = require('./shared/eq');
8954
8955describe('groupWith', function() {
8956 it('can be turned into the original list through concatenation', function() {
8957 var list = [1, 1, 2, 3, 4, 4, 5, 5];
8958 eq(R.unnest(R.groupWith(R.equals, list)), list);
8959 eq(R.unnest(R.groupWith(R.complement(R.equals), list)), list);
8960 eq(R.unnest(R.groupWith(R.T, list)), list);
8961 eq(R.unnest(R.groupWith(R.F, list)), list);
8962 });
8963 it('also works on strings', function() {
8964 eq(R.groupWith(R.equals)('Mississippi'), ['M','i','ss','i','ss','i','pp','i']);
8965 });
8966});
8967```
8968
8969</details>
8970
8971[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#groupWith)
8972
8973### has
8974
8975```typescript
8976
8977has<T>(prop: string, obj: T): boolean
8978```
8979
8980It returns `true` if `obj` has property `prop`.
8981
8982```javascript
8983const obj = {a: 1}
8984
8985const result = [
8986 R.has('a', obj),
8987 R.has('b', obj)
8988]
8989// => [true, false]
8990```
8991
8992<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7Ba%3A%201%7D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.has('a'%2C%20obj)%2C%0A%20%20R.has('b'%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.has</strong> example in Rambda REPL</a>
8993
8994<details>
8995
8996<summary>All Typescript definitions</summary>
8997
8998```typescript
8999has<T>(prop: string, obj: T): boolean;
9000has(prop: string): <T>(obj: T) => boolean;
9001```
9002
9003</details>
9004
9005<details>
9006
9007<summary><strong>R.has</strong> source</summary>
9008
9009```javascript
9010export function has(prop, obj){
9011 if (arguments.length === 1) return _obj => has(prop, _obj)
9012
9013 if (!obj) return false
9014
9015 return obj[ prop ] !== undefined
9016}
9017```
9018
9019</details>
9020
9021<details>
9022
9023<summary><strong>Tests</strong></summary>
9024
9025```javascript
9026import { has } from './has'
9027
9028test('happy', () => {
9029 expect(has('a')({ a : 1 })).toBeTrue()
9030 expect(has('b', { a : 1 })).toBeFalse()
9031})
9032
9033test('with non-object', () => {
9034 expect(has('a', undefined)).toEqual(false)
9035 expect(has('a', null)).toEqual(false)
9036 expect(has('a', true)).toEqual(false)
9037 expect(has('a', '')).toEqual(false)
9038 expect(has('a', /a/)).toEqual(false)
9039})
9040```
9041
9042</details>
9043
9044<details>
9045
9046<summary><strong>Typescript</strong> test</summary>
9047
9048```typescript
9049import {has} from 'rambda'
9050
9051describe('R.has', () => {
9052 it('happy', () => {
9053 const result = has('foo', {a: 1})
9054 const curriedResult = has('bar')({a: 1})
9055 result // $ExpectType boolean
9056 curriedResult // $ExpectType boolean
9057 })
9058})
9059```
9060
9061</details>
9062
9063<details>
9064
9065<summary>1 failed <italic>Ramda.has</italic> specs
9066
9067> :boom: Reason for the failure: Rambda method does check properties from the prototype chain
9068</summary>
9069
9070```javascript
9071var R = require('../../../../dist/rambda.js');
9072var eq = require('./shared/eq');
9073
9074describe('has', function() {
9075 var fred = {name: 'Fred', age: 23};
9076 var anon = {age: 99};
9077 it('does not check properties from the prototype chain', function() {
9078 var Person = function() {};
9079 Person.prototype.age = function() {};
9080 var bob = new Person();
9081 eq(R.has('age', bob), false);
9082 });
9083});
9084```
9085
9086</details>
9087
9088[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#has)
9089
9090### hasPath
9091
9092```typescript
9093
9094hasPath<T>(
9095 path: string | readonly string[],
9096 input: object
9097): boolean
9098```
9099
9100It will return true, if `input` object has truthy `path`(calculated with `R.path`).
9101
9102```javascript
9103const path = 'a.b'
9104const pathAsArray = ['a', 'b']
9105const obj = {a: {b: []}}
9106
9107const result = [
9108 R.hasPath(path, obj),
9109 R.hasPath(pathAsArray, obj),
9110 R.hasPath('a.c', obj),
9111]
9112// => [true, true, false]
9113```
9114
9115<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20path%20%3D%20'a.b'%0Aconst%20pathAsArray%20%3D%20%5B'a'%2C%20'b'%5D%0Aconst%20obj%20%3D%20%7Ba%3A%20%7Bb%3A%20%5B%5D%7D%7D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.hasPath(path%2C%20obj)%2C%0A%20%20R.hasPath(pathAsArray%2C%20obj)%2C%0A%20%20R.hasPath('a.c'%2C%20obj)%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20true%2C%20false%5D">Try this <strong>R.hasPath</strong> example in Rambda REPL</a>
9116
9117<details>
9118
9119<summary>All Typescript definitions</summary>
9120
9121```typescript
9122hasPath<T>(
9123 path: string | readonly string[],
9124 input: object
9125): boolean;
9126hasPath<T>(
9127 path: string | readonly string[]
9128): (input: object) => boolean;
9129```
9130
9131</details>
9132
9133<details>
9134
9135<summary><strong>R.hasPath</strong> source</summary>
9136
9137```javascript
9138import { path } from './path'
9139
9140export function hasPath(maybePath, obj){
9141 if (arguments.length === 1){
9142 return objHolder => hasPath(maybePath, objHolder)
9143 }
9144
9145 return path(maybePath, obj) !== undefined
9146}
9147```
9148
9149</details>
9150
9151<details>
9152
9153<summary><strong>Tests</strong></summary>
9154
9155```javascript
9156import { hasPath } from './hasPath'
9157
9158test('when true', () => {
9159 const path = 'a.b'
9160 const obj = { a : { b : [] } }
9161
9162 const result = hasPath(path)(obj)
9163 const expectedResult = true
9164
9165 expect(result).toEqual(expectedResult)
9166})
9167
9168test('when false', () => {
9169 const path = 'a.b'
9170 const obj = {}
9171
9172 const result = hasPath(path, obj)
9173 const expectedResult = false
9174
9175 expect(result).toEqual(expectedResult)
9176})
9177```
9178
9179</details>
9180
9181<details>
9182
9183<summary><strong>Typescript</strong> test</summary>
9184
9185```typescript
9186import {hasPath} from 'rambda'
9187
9188describe('R.hasPath', () => {
9189 it('string path', () => {
9190 const obj = {a: {b: 1}}
9191 const result = hasPath('a.b', obj)
9192 const curriedResult = hasPath('a.c')(obj)
9193 result // $ExpectType boolean
9194 curriedResult // $ExpectType boolean
9195 })
9196 it('array path', () => {
9197 const obj = {a: {b: 1}}
9198 const result = hasPath(['a', 'b'], obj)
9199 const curriedResult = hasPath(['a', 'c'])(obj)
9200 result // $ExpectType boolean
9201 curriedResult // $ExpectType boolean
9202 })
9203})
9204```
9205
9206</details>
9207
9208[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#hasPath)
9209
9210### head
9211
9212```typescript
9213
9214head<T>(input: readonly T[]): T | undefined
9215```
9216
9217It returns the first element of list or string `input`.
9218
9219```javascript
9220const result = [
9221 R.head([1, 2, 3]),
9222 R.head('foo')
9223]
9224// => [1, 'f']
9225```
9226
9227<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.head(%5B1%2C%202%2C%203%5D)%2C%0A%20%20R.head('foo')%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B1%2C%20'f'%5D">Try this <strong>R.head</strong> example in Rambda REPL</a>
9228
9229<details>
9230
9231<summary>All Typescript definitions</summary>
9232
9233```typescript
9234head<T>(input: readonly T[]): T | undefined;
9235head(input: string): string;
9236```
9237
9238</details>
9239
9240<details>
9241
9242<summary><strong>R.head</strong> source</summary>
9243
9244```javascript
9245export function head(listOrString){
9246 if (typeof listOrString === 'string') return listOrString[ 0 ] || ''
9247
9248 return listOrString[ 0 ]
9249}
9250```
9251
9252</details>
9253
9254<details>
9255
9256<summary><strong>Tests</strong></summary>
9257
9258```javascript
9259import { head } from './head'
9260
9261test('head', () => {
9262 expect(head([ 'fi', 'fo', 'fum' ])).toEqual('fi')
9263 expect(head([])).toEqual(undefined)
9264 expect(head('foo')).toEqual('f')
9265 expect(head('')).toEqual('')
9266})
9267```
9268
9269</details>
9270
9271<details>
9272
9273<summary><strong>Typescript</strong> test</summary>
9274
9275```typescript
9276import {head} from 'rambda'
9277
9278describe('R.head', () => {
9279 it('string', () => {
9280 const result = head('foo')
9281 result // $ExpectType string
9282 })
9283 it('array', () => {
9284 const result = head([1, 2, 3])
9285 result // $ExpectType number | undefined
9286 })
9287})
9288```
9289
9290</details>
9291
9292[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#head)
9293
9294### identical
9295
9296```typescript
9297
9298identical<T>(x: T, y: T): boolean
9299```
9300
9301It returns `true` if its arguments `a` and `b` are identical.
9302
9303Otherwise, it returns `false`.
9304
9305> :boom: Values are identical if they reference the same memory. `NaN` is identical to `NaN`; `0` and `-0` are not identical.
9306
9307```javascript
9308const obj = {a: 1};
9309R.identical(obj, obj); //=> true
9310R.identical(1, 1); //=> true
9311R.identical(1, '1'); //=> false
9312R.identical([], []); //=> false
9313R.identical(0, -0); //=> false
9314R.identical(NaN, NaN); //=> true
9315```
9316
9317<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20obj%20%3D%20%7Ba%3A%201%7D%3B%0AR.identical(obj%2C%20obj)%3B%20%2F%2F%3D%3E%20true%0AR.identical(1%2C%201)%3B%20%2F%2F%3D%3E%20true%0AR.identical(1%2C%20'1')%3B%20%2F%2F%3D%3E%20false%0AR.identical(%5B%5D%2C%20%5B%5D)%3B%20%2F%2F%3D%3E%20false%0AR.identical(0%2C%20-0)%3B%20%2F%2F%3D%3E%20false%0AR.identical(NaN%2C%20NaN)%3B%20%2F%2F%3D%3E%20true">Try this <strong>R.identical</strong> example in Rambda REPL</a>
9318
9319<details>
9320
9321<summary>All Typescript definitions</summary>
9322
9323```typescript
9324identical<T>(x: T, y: T): boolean;
9325identical<T>(x: T): (y: T) => boolean;
9326```
9327
9328</details>
9329
9330<details>
9331
9332<summary><strong>R.identical</strong> source</summary>
9333
9334```javascript
9335import _objectIs from './_internals/_objectIs'
9336
9337export function identical(a, b){
9338 if (arguments.length === 1) return _b => identical(a, _b)
9339
9340 return _objectIs(a, b)
9341}
9342```
9343
9344</details>
9345
9346<details>
9347
9348<summary><strong>Tests</strong></summary>
9349
9350```javascript
9351import { F, T } from '../rambda'
9352import { _isInteger } from './_internals/_isInteger'
9353import { _objectIs } from './_internals/_objectIs'
9354import { identical } from './identical'
9355
9356test('with boolean', () => {
9357 expect(F()).toBeFalse()
9358 expect(T()).toBeTrue()
9359})
9360
9361test('internal isInteger', () => {
9362 expect(_isInteger(1)).toBeTrue()
9363 expect(_isInteger(0.3)).toBeFalse()
9364})
9365
9366test('internal objectIs', () => {
9367 expect(_objectIs(1, 1)).toBeTrue()
9368 expect(_objectIs(NaN, NaN)).toBeTrue()
9369})
9370
9371test('identical', () => {
9372 const a = {}
9373
9374 expect(identical(100)(100)).toEqual(true)
9375 expect(identical(100, '100')).toEqual(false)
9376 expect(identical('string', 'string')).toEqual(true)
9377 expect(identical([], [])).toEqual(false)
9378 expect(identical(a, a)).toEqual(true)
9379 expect(identical(undefined, undefined)).toEqual(true)
9380 expect(identical(null, undefined)).toEqual(false)
9381})
9382```
9383
9384</details>
9385
9386<details>
9387
9388<summary><strong>Typescript</strong> test</summary>
9389
9390```typescript
9391import {identical} from 'rambda'
9392
9393describe('R.identical', () => {
9394 it('happy', () => {
9395 const result = identical(4, 1)
9396 const curriedResult = identical(4)(1)
9397 result // $ExpectType boolean
9398 curriedResult // $ExpectType boolean
9399 })
9400 it('with object', () => {
9401 const result = identical({a: 1}, {b: 2})
9402 result // $ExpectType boolean
9403 })
9404})
9405
9406/*
9407 in curried version Typescript correctly catch errors
9408 but it doesn't do so in the standart definition
9409
9410 identical({a:1},{b:2})
9411 identical({a:1})({b:2})
9412*/
9413```
9414
9415</details>
9416
9417[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#identical)
9418
9419### identity
9420
9421```typescript
9422
9423identity<T>(input: T): T
9424```
9425
9426It just passes back the supplied `input` argument.
9427
9428> :boom: Logic
9429
9430```javascript
9431R.identity(7) // => 7
9432```
9433
9434<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.identity(7)%20%2F%2F%20%3D%3E%207">Try this <strong>R.identity</strong> example in Rambda REPL</a>
9435
9436<details>
9437
9438<summary>All Typescript definitions</summary>
9439
9440```typescript
9441identity<T>(input: T): T;
9442```
9443
9444</details>
9445
9446<details>
9447
9448<summary><strong>R.identity</strong> source</summary>
9449
9450```javascript
9451export function identity(input){
9452 return input
9453}
9454```
9455
9456</details>
9457
9458<details>
9459
9460<summary><strong>Tests</strong></summary>
9461
9462```javascript
9463import { identity } from './identity'
9464
9465test('happy', () => {
9466 expect(identity(7)).toEqual(7)
9467 expect(identity(true)).toEqual(true)
9468 expect(identity({ a : 1 })).toEqual({ a : 1 })
9469})
9470```
9471
9472</details>
9473
9474<details>
9475
9476<summary><strong>Typescript</strong> test</summary>
9477
9478```typescript
9479import {identity} from 'rambda'
9480
9481describe('R.identity', () => {
9482 it('happy', () => {
9483 const result = identity(4)
9484 result // $ExpectType 4
9485 })
9486})
9487```
9488
9489</details>
9490
9491[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#identity)
9492
9493### ifElse
9494
9495```typescript
9496
9497ifElse<T, U>(
9498 condition: (x: T) => boolean,
9499 onTrue: (x: T) => U,
9500 onFalse: (x: T) => U,
9501): (x: T) => U
9502```
9503
9504It expects `condition`, `onTrue` and `onFalse` functions as inputs and it returns a new function with example name of `fn`.
9505
9506When `fn`` is called with `input` argument, it will return either `onTrue(input)` or `onFalse(input)` depending on `condition(input)` evaluation.
9507
9508```javascript
9509const fn = R.ifElse(
9510 x => x>10,
9511 x => x*2,
9512 x => x*10
9513)
9514
9515const result = [ fn(8), fn(18) ]
9516// => [80, 36]
9517```
9518
9519<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20R.ifElse(%0A%20x%20%3D%3E%20x%3E10%2C%0A%20x%20%3D%3E%20x*2%2C%0A%20x%20%3D%3E%20x*10%0A)%0A%0Aconst%20result%20%3D%20%5B%20fn(8)%2C%20fn(18)%20%5D%0A%2F%2F%20%3D%3E%20%5B80%2C%2036%5D">Try this <strong>R.ifElse</strong> example in Rambda REPL</a>
9520
9521<details>
9522
9523<summary>All Typescript definitions</summary>
9524
9525```typescript
9526ifElse<T, U>(
9527 condition: (x: T) => boolean,
9528 onTrue: (x: T) => U,
9529 onFalse: (x: T) => U,
9530): (x: T) => U;
9531ifElse<T, K, U>(
9532 condition: (x: T, y: K) => boolean,
9533 onTrue: (x: T, y: K) => U,
9534 onFalse: (x: T, y: K) => U,
9535): (x: T, y: K) => U;
9536```
9537
9538</details>
9539
9540<details>
9541
9542<summary><strong>R.ifElse</strong> source</summary>
9543
9544```javascript
9545import { curry } from './curry'
9546
9547function ifElseFn(
9548 condition, onTrue, onFalse
9549){
9550 return (...input) => {
9551 const conditionResult =
9552 typeof condition === 'boolean' ? condition : condition(...input)
9553
9554 if (conditionResult === true){
9555 return onTrue(...input)
9556 }
9557
9558 return onFalse(...input)
9559 }
9560}
9561
9562export const ifElse = curry(ifElseFn)
9563```
9564
9565</details>
9566
9567<details>
9568
9569<summary><strong>Tests</strong></summary>
9570
9571```javascript
9572import { always } from './always'
9573import { has } from './has'
9574import { identity } from './identity'
9575import { ifElse } from './ifElse'
9576import { prop } from './prop'
9577
9578const condition = has('foo')
9579const v = function (a){
9580 return typeof a === 'number'
9581}
9582const t = function (a){
9583 return a + 1
9584}
9585const ifFn = x => prop('foo', x).length
9586const elseFn = () => false
9587
9588test('happy', () => {
9589 const fn = ifElse(condition, ifFn)(elseFn)
9590
9591 expect(fn({ foo : 'bar' })).toEqual(3)
9592 expect(fn({ fo : 'bar' })).toEqual(false)
9593})
9594
9595test('ramda spec', () => {
9596 const ifIsNumber = ifElse(v)
9597 expect(ifIsNumber(t, identity)(15)).toEqual(16)
9598 expect(ifIsNumber(t, identity)('hello')).toEqual('hello')
9599})
9600
9601test('pass all arguments', () => {
9602 const identity = function (a){
9603 return a
9604 }
9605 const v = function (){
9606 return true
9607 }
9608 const onTrue = function (a, b){
9609 expect(a).toEqual(123)
9610 expect(b).toEqual('abc')
9611 }
9612 ifElse(
9613 v, onTrue, identity
9614 )(123, 'abc')
9615})
9616
9617test('accept constant as condition', () => {
9618 const fn = ifElse(true)(always(true))(always(false))
9619
9620 expect(fn()).toEqual(true)
9621})
9622
9623test('accept constant as condition - case 2', () => {
9624 const fn = ifElse(
9625 false, always(true), always(false)
9626 )
9627
9628 expect(fn()).toEqual(false)
9629})
9630
9631test('curry 1', () => {
9632 const fn = ifElse(condition, ifFn)(elseFn)
9633
9634 expect(fn({ foo : 'bar' })).toEqual(3)
9635 expect(fn({ fo : 'bar' })).toEqual(false)
9636})
9637
9638test('curry 2', () => {
9639 const fn = ifElse(condition)(ifFn)(elseFn)
9640
9641 expect(fn({ foo : 'bar' })).toEqual(3)
9642 expect(fn({ fo : 'bar' })).toEqual(false)
9643})
9644
9645test('simple arity of 1', () => {
9646 const condition = x => x > 5
9647 const onTrue = x => x + 1
9648 const onFalse = x => x + 10
9649 const result = ifElse(
9650 condition, onTrue, onFalse
9651 )(1)
9652 expect(result).toBe(11)
9653})
9654
9655test('simple arity of 2', () => {
9656 const condition = (x, y) => x + y > 5
9657 const onTrue = (x, y) => x + y + 1
9658 const onFalse = (x, y) => x + y + 10
9659 const result = ifElse(
9660 condition, onTrue, onFalse
9661 )(1, 10)
9662 expect(result).toBe(12)
9663})
9664```
9665
9666</details>
9667
9668<details>
9669
9670<summary><strong>Typescript</strong> test</summary>
9671
9672```typescript
9673import {ifElse} from 'rambda'
9674
9675describe('R.ifElse', () => {
9676 it('happy', () => {
9677 const condition = (x: number) => x > 5
9678 const onTrue = (x: number) => `foo${x}`
9679 const onFalse = (x: number) => `bar${x}`
9680 const fn = ifElse(condition, onTrue, onFalse)
9681 fn // $ExpectType (x: number) => string
9682 const result = fn(3)
9683 result // $ExpectType string
9684 })
9685 it('arity of 2', () => {
9686 const condition = (x: number, y: string) => x + y.length > 5
9687 const onTrue = (x: number, y: string) => `foo${x}-${y}`
9688 const onFalse = (x: number, y: string) => `bar${x}-${y}`
9689 const fn = ifElse(condition, onTrue, onFalse)
9690 fn // $ExpectType (x: number, y: string) => string
9691 const result = fn(3, 'hello')
9692 result // $ExpectType string
9693 })
9694})
9695```
9696
9697</details>
9698
9699<details>
9700
9701<summary>2 failed <italic>Ramda.ifElse</italic> specs
9702
9703> :boom: Reason for the failure: Rambda method doesn't return a curried function
9704</summary>
9705
9706```javascript
9707var R = require('../../../../dist/rambda.js');
9708var eq = require('./shared/eq');
9709
9710describe('ifElse', function() {
9711 var t = function(a) { return a + 1; };
9712 var identity = function(a) { return a; };
9713 var isArray = function(a) { return Object.prototype.toString.call(a) === '[object Array]'; };
9714 it('returns a function whose arity equals the max arity of the three arguments to `ifElse`', function() {
9715 function a0() { return 0; }
9716 function a1(x) { return x; }
9717 function a2(x, y) { return x + y; }
9718 eq(R.ifElse(a0, a1, a2).length, 2);
9719 eq(R.ifElse(a0, a2, a1).length, 2);
9720 eq(R.ifElse(a1, a0, a2).length, 2);
9721 eq(R.ifElse(a1, a2, a0).length, 2);
9722 eq(R.ifElse(a2, a0, a1).length, 2);
9723 eq(R.ifElse(a2, a1, a0).length, 2);
9724 });
9725 it('returns a curried function', function() {
9726 var v = function(a) { return typeof a === 'number'; };
9727 var ifIsNumber = R.ifElse(v);
9728 eq(ifIsNumber(t, identity)(15), 16);
9729 eq(ifIsNumber(t, identity)('hello'), 'hello');
9730 var fn = R.ifElse(R.gt, R.subtract, R.add);
9731 eq(fn(2)(7), 9);
9732 eq(fn(2, 7), 9);
9733 eq(fn(7)(2), 5);
9734 eq(fn(7, 2), 5);
9735 });
9736});
9737```
9738
9739</details>
9740
9741[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#ifElse)
9742
9743### inc
9744
9745```typescript
9746
9747inc(x: number): number
9748```
9749
9750It increments a number.
9751
9752```javascript
9753R.inc(1) // => 2
9754```
9755
9756<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.inc(1)%20%2F%2F%20%3D%3E%202">Try this <strong>R.inc</strong> example in Rambda REPL</a>
9757
9758<details>
9759
9760<summary>All Typescript definitions</summary>
9761
9762```typescript
9763inc(x: number): number;
9764```
9765
9766</details>
9767
9768<details>
9769
9770<summary><strong>R.inc</strong> source</summary>
9771
9772```javascript
9773export const inc = x => x + 1
9774```
9775
9776</details>
9777
9778<details>
9779
9780<summary><strong>Tests</strong></summary>
9781
9782```javascript
9783import { inc } from './inc'
9784
9785test('happy', () => {
9786 expect(inc(1)).toBe(2)
9787})
9788```
9789
9790</details>
9791
9792[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#inc)
9793
9794### includes
9795
9796```typescript
9797
9798includes(valueToFind: string, input: readonly string[] | string): boolean
9799```
9800
9801If `input` is string, then this method work as native `String.includes`.
9802
9803If `input` is array, then `R.equals` is used to define if `valueToFind` belongs to the list.
9804
9805```javascript
9806const result = [
9807 R.includes('oo', 'foo'),
9808 R.includes({a: 1}, [{a: 1}])
9809]
9810// => [true, true ]
9811```
9812
9813<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.includes('oo'%2C%20'foo')%2C%0A%20%20R.includes(%7Ba%3A%201%7D%2C%20%5B%7Ba%3A%201%7D%5D)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20true%20%5D">Try this <strong>R.includes</strong> example in Rambda REPL</a>
9814
9815<details>
9816
9817<summary>All Typescript definitions</summary>
9818
9819```typescript
9820includes(valueToFind: string, input: readonly string[] | string): boolean;
9821includes(valueToFind: string): (input: readonly string[] | string) => boolean;
9822includes<T>(valueToFind: T, input: readonly T[]): boolean;
9823includes<T>(valueToFind: T): (input: readonly T[]) => boolean;
9824```
9825
9826</details>
9827
9828<details>
9829
9830<summary><strong>R.includes</strong> source</summary>
9831
9832```javascript
9833import { _isArray } from './_internals/_isArray'
9834import { equals } from './equals'
9835
9836export function includes(valueToFind, input){
9837 if (arguments.length === 1) return _input => includes(valueToFind, _input)
9838 if (typeof input === 'string'){
9839 return input.includes(valueToFind)
9840 }
9841 if (!input){
9842 throw new TypeError(`Cannot read property \'indexOf\' of ${ input }`)
9843 }
9844 if (!_isArray(input)) return false
9845
9846 let index = -1
9847
9848 while (++index < input.length){
9849 if (equals(input[ index ], valueToFind)){
9850 return true
9851 }
9852 }
9853
9854 return false
9855}
9856```
9857
9858</details>
9859
9860<details>
9861
9862<summary><strong>Tests</strong></summary>
9863
9864```javascript
9865import R from 'ramda'
9866
9867import { includes } from './includes'
9868
9869test('includes with string', () => {
9870 const str = 'foo bar'
9871
9872 expect(includes('bar')(str)).toBeTrue()
9873 expect(R.includes('bar')(str)).toBeTrue()
9874 expect(includes('never', str)).toBeFalse()
9875 expect(R.includes('never', str)).toBeFalse()
9876})
9877
9878test('includes with array', () => {
9879 const arr = [ 1, 2, 3 ]
9880
9881 expect(includes(2)(arr)).toBeTrue()
9882 expect(R.includes(2)(arr)).toBeTrue()
9883
9884 expect(includes(4, arr)).toBeFalse()
9885 expect(R.includes(4, arr)).toBeFalse()
9886})
9887
9888test('with wrong input that does not throw', () => {
9889 const result = includes(1, /foo/g)
9890 const ramdaResult = R.includes(1, /foo/g)
9891 expect(result).toBeFalse()
9892 expect(ramdaResult).toBeFalse()
9893})
9894
9895test('throws on wrong input - match ramda behaviour', () => {
9896 expect(() => includes(2, null)).toThrowWithMessage(TypeError,
9897 'Cannot read property \'indexOf\' of null')
9898 expect(() => R.includes(2, null)).toThrowWithMessage(TypeError,
9899 'Cannot read property \'indexOf\' of null')
9900 expect(() => includes(2, undefined)).toThrowWithMessage(TypeError,
9901 'Cannot read property \'indexOf\' of undefined')
9902 expect(() => R.includes(2, undefined)).toThrowWithMessage(TypeError,
9903 'Cannot read property \'indexOf\' of undefined')
9904})
9905```
9906
9907</details>
9908
9909<details>
9910
9911<summary><strong>Typescript</strong> test</summary>
9912
9913```typescript
9914import {includes} from 'ramda'
9915
9916const list = [{a: {b: '1'}}, {a: {c: '2'}}, {a: {b: '3'}}]
9917
9918describe('R.includes', () => {
9919 it('happy', () => {
9920 const result = includes({a: {b: '1'}}, list)
9921 /*
9922 should work:
9923
9924 const resultCurried = includes({a: {b: '1'}})(list)
9925 */
9926 result // $ExpectType boolean
9927 result // $ExpectType boolean
9928 })
9929 it('with string', () => {
9930 const result = includes('oo', 'foo')
9931 const resultCurried = includes('oo')('foo')
9932
9933 result // $ExpectType boolean
9934 resultCurried // $ExpectType boolean
9935 })
9936})
9937```
9938
9939</details>
9940
9941<details>
9942
9943<summary>1 failed <italic>Ramda.includes</italic> specs
9944
9945> :boom: Reason for the failure: Ramda method pass to `equals` method if available
9946</summary>
9947
9948```javascript
9949var R = require('../../../../dist/rambda.js');
9950var eq = require('./shared/eq');
9951
9952describe('includes', function() {
9953 it('has R.equals semantics', function() {
9954 function Just(x) { this.value = x; }
9955 Just.prototype.equals = function(x) {
9956 return x instanceof Just && R.equals(x.value, this.value);
9957 };
9958 eq(R.includes(0, [-0]), false);
9959 eq(R.includes(-0, [0]), false);
9960 eq(R.includes(NaN, [NaN]), true);
9961 eq(R.includes(new Just([42]), [new Just([42])]), true);
9962 });
9963});
9964```
9965
9966</details>
9967
9968[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#includes)
9969
9970### indexBy
9971
9972```typescript
9973
9974indexBy<T>(condition: (x: T) => string, list: readonly T[]): { [key: string]: T }
9975```
9976
9977It generates object with properties provided by `condition` and values provided by `list` array.
9978
9979If `condition` is a function, then all list members are passed through it.
9980
9981If `condition` is a string, then all list members are passed through `R.path(condition)`.
9982
9983```javascript
9984const list = [ {id: 10}, {id: 20} ]
9985
9986const withFunction = R.indexBy(
9987 x => x.id,
9988 list
9989)
9990const withString = R.indexBy(
9991 'id',
9992 list
9993)
9994const result = [
9995 withFunction,
9996 R.equals(withFunction, withString)
9997]
9998// => [ { 10: {id: 10}, 20: {id: 20} }, true ]
9999```
10000
10001<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%20%7Bid%3A%2010%7D%2C%20%7Bid%3A%2020%7D%20%5D%0A%0Aconst%20withFunction%20%3D%20R.indexBy(%0A%20%20x%20%3D%3E%20x.id%2C%0A%20%20list%0A)%0Aconst%20withString%20%3D%20R.indexBy(%0A%20%20'id'%2C%0A%20%20list%0A)%0Aconst%20result%20%3D%20%5B%0A%20%20withFunction%2C%20%0A%20%20R.equals(withFunction%2C%20withString)%0A%5D%0A%2F%2F%20%3D%3E%20%5B%20%7B%2010%3A%20%7Bid%3A%2010%7D%2C%2020%3A%20%7Bid%3A%2020%7D%20%7D%2C%20true%20%5D">Try this <strong>R.indexBy</strong> example in Rambda REPL</a>
10002
10003<details>
10004
10005<summary>All Typescript definitions</summary>
10006
10007```typescript
10008indexBy<T>(condition: (x: T) => string, list: readonly T[]): { [key: string]: T };
10009indexBy<T>(condition: string, list: readonly T[]): { [key: string]: T };
10010indexBy<T>(condition: (x: T) => string): (list: readonly T[]) => { [key: string]: T };
10011indexBy<T>(condition: string): (list: readonly T[]) => { [key: string]: T };
10012```
10013
10014</details>
10015
10016<details>
10017
10018<summary><strong>R.indexBy</strong> source</summary>
10019
10020```javascript
10021import { path } from './path'
10022
10023function indexByPath(pathInput, list){
10024 const toReturn = {}
10025 for (let i = 0; i < list.length; i++){
10026 const item = list[ i ]
10027 toReturn[ path(pathInput, item) ] = item
10028 }
10029
10030 return toReturn
10031}
10032
10033export function indexBy(condition, list){
10034 if (arguments.length === 1){
10035 return _list => indexBy(condition, _list)
10036 }
10037
10038 if (typeof condition === 'string'){
10039 return indexByPath(condition, list)
10040 }
10041
10042 const toReturn = {}
10043 for (let i = 0; i < list.length; i++){
10044 const item = list[ i ]
10045 toReturn[ condition(item) ] = item
10046 }
10047
10048 return toReturn
10049}
10050```
10051
10052</details>
10053
10054<details>
10055
10056<summary><strong>Tests</strong></summary>
10057
10058```javascript
10059import { indexBy } from './indexBy'
10060import { prop } from './prop'
10061
10062test('happy', () => {
10063 const list = [
10064 { id : 1 },
10065 {
10066 id : 1,
10067 a : 2,
10068 },
10069 { id : 2 },
10070 { id : 10 },
10071 { id : 'a' },
10072 ]
10073
10074 expect(indexBy(prop('id'))(list)).toEqual({
10075 1 : {
10076 id : 1,
10077 a : 2,
10078 },
10079 2 : { id : 2 },
10080 10 : { id : 10 },
10081 a : { id : 'a' },
10082 })
10083})
10084
10085test('with string as condition', () => {
10086 const list = [ { id : 1 }, { id : 2 }, { id : 10 }, { id : 'a' } ]
10087 const standardResult = indexBy(obj => obj.id, list)
10088 const suggestionResult = indexBy('id', list)
10089
10090 expect(standardResult).toEqual(suggestionResult)
10091})
10092
10093test('with string - bad path', () => {
10094 const list = [
10095 {
10096 a : {
10097 b : 1,
10098 c : 2,
10099 },
10100 },
10101 { a : { c : 4 } },
10102 {},
10103 {
10104 a : {
10105 b : 10,
10106 c : 20,
10107 },
10108 },
10109 ]
10110
10111 const result = indexBy('a.b', list)
10112 const expected = {
10113 1 : {
10114 a : {
10115 b : 1,
10116 c : 2,
10117 },
10118 },
10119 10 : {
10120 a : {
10121 b : 10,
10122 c : 20,
10123 },
10124 },
10125 undefined : {},
10126 }
10127
10128 expect(result).toEqual(expected)
10129})
10130```
10131
10132</details>
10133
10134<details>
10135
10136<summary><strong>Typescript</strong> test</summary>
10137
10138```typescript
10139import {indexBy} from 'rambda'
10140
10141const list = [{a: {b: '1'}}, {a: {c: '2'}}, {a: {b: '3'}}]
10142
10143describe('indexBy', () => {
10144 it('happy', () => {
10145 const result = indexBy<any>(x => x.a.b, list)
10146 const resultCurried = indexBy<any>(x => x.a.b)(list)
10147 result // $ExpectType { [key: string]: any; }
10148 resultCurried // $ExpectType { [key: string]: any; }
10149 })
10150
10151 it('with string', () => {
10152 const result = indexBy<any>('a.b', list)
10153 const resultCurried = indexBy<any>('a.b')(list)
10154 result // $ExpectType { [key: string]: any; }
10155 resultCurried // $ExpectType { [key: string]: any; }
10156 })
10157
10158 it('with interface', () => {
10159 interface Foo {
10160 a: string,
10161 }
10162 const interfaceList = [{a: 'foo'}, {a: 'bar'}]
10163 const result = indexBy<Foo>(x => {
10164 x.a // $ExpectType string
10165 return x.a
10166 }, interfaceList)
10167 const resultCurried = indexBy<Foo>(x => {
10168 x.a // $ExpectType string
10169 return x.a
10170 })(interfaceList)
10171 result // $ExpectType { [key: string]: Foo; }
10172 resultCurried // $ExpectType { [key: string]: Foo; }
10173 })
10174})
10175```
10176
10177</details>
10178
10179<details>
10180
10181<summary>1 failed <italic>Ramda.indexBy</italic> specs
10182
10183> :boom: Reason for the failure: Ramda method can act as a transducer
10184</summary>
10185
10186```javascript
10187var R = require('../../../../dist/rambda.js');
10188var eq = require('./shared/eq');
10189
10190describe('indexBy', function() {
10191 it('can act as a transducer', function() {
10192 var list = [{id: 'xyz', title: 'A'}, {id: 'abc', title: 'B'}];
10193 var transducer = R.compose(
10194 R.indexBy(R.prop('id')),
10195 R.map(R.pipe(
10196 R.adjust(0, R.toUpper),
10197 R.adjust(1, R.omit(['id']))
10198 )));
10199 var result = R.into({}, transducer, list);
10200 eq(result, {ABC: {title: 'B'}, XYZ: {title: 'A'}});
10201 });
10202});
10203```
10204
10205</details>
10206
10207[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#indexBy)
10208
10209### indexOf
10210
10211```typescript
10212
10213indexOf<T>(valueToFind: T, list: readonly T[]): number
10214```
10215
10216It returns the index of the first element of `list` equals to `valueToFind`.
10217
10218If there is no such element, it returns `-1`.
10219
10220```javascript
10221const list = [0, 1, 2, 3]
10222
10223const result = [
10224 R.indexOf(2, list),
10225 R.indexOf(0, list)
10226]
10227// => [2, -1]
10228```
10229
10230<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B0%2C%201%2C%202%2C%203%5D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.indexOf(2%2C%20list)%2C%0A%20%20R.indexOf(0%2C%20list)%0A%5D%0A%2F%2F%20%3D%3E%20%5B2%2C%20-1%5D">Try this <strong>R.indexOf</strong> example in Rambda REPL</a>
10231
10232<details>
10233
10234<summary>All Typescript definitions</summary>
10235
10236```typescript
10237indexOf<T>(valueToFind: T, list: readonly T[]): number;
10238indexOf<T>(valueToFind: T): (list: readonly T[]) => number;
10239```
10240
10241</details>
10242
10243<details>
10244
10245<summary><strong>R.indexOf</strong> source</summary>
10246
10247```javascript
10248export function indexOf(valueToFind, list){
10249 if (arguments.length === 1){
10250 return _list => indexOf(valueToFind, _list)
10251 }
10252
10253 let index = -1
10254 const { length } = list
10255
10256 while (++index < length){
10257 if (list[ index ] === valueToFind){
10258 return index
10259 }
10260 }
10261
10262 return -1
10263}
10264```
10265
10266</details>
10267
10268<details>
10269
10270<summary><strong>Tests</strong></summary>
10271
10272```javascript
10273import { indexOf } from './indexOf'
10274
10275test('happy', () => {
10276 expect(indexOf(3, [ 1, 2, 3, 4 ])).toEqual(2)
10277
10278 expect(indexOf(10)([ 1, 2, 3, 4 ])).toEqual(-1)
10279})
10280```
10281
10282</details>
10283
10284<details>
10285
10286<summary><strong>Typescript</strong> test</summary>
10287
10288```typescript
10289import {indexOf} from 'rambda'
10290
10291describe('R.indexOf', () => {
10292 it('happy', () => {
10293 const list = [1, 2, 3]
10294 const result = indexOf(1, list)
10295 const curriedResult = indexOf(1)(list)
10296
10297 result // $ExpectType number
10298 curriedResult // $ExpectType number
10299 })
10300})
10301```
10302
10303</details>
10304
10305<details>
10306
10307<summary>2 failed <italic>Ramda.indexOf</italic> specs
10308
10309> :boom: Reason for the failure: Ramda method dispatches to `indexOf` method
10310</summary>
10311
10312```javascript
10313var R = require('../../../../dist/rambda.js');
10314var eq = require('./shared/eq');
10315
10316describe('indexOf', function() {
10317 var input = [1, 2, 3, 4, 5];
10318 var list = [1, 2, 3];
10319 list[-2] = 4; // Throw a wrench in the gears by assigning a non-valid array index as object property.
10320 it('has R.equals semantics', function() {
10321 function Just(x) { this.value = x; }
10322 Just.prototype.equals = function(x) {
10323 return x instanceof Just && R.equals(x.value, this.value);
10324 };
10325 eq(R.indexOf(0, [-0]), -1);
10326 eq(R.indexOf(-0, [0]), -1);
10327 eq(R.indexOf(NaN, [NaN]), 0);
10328 eq(R.indexOf(new Just([42]), [new Just([42])]), 0);
10329 });
10330 it('dispatches to `indexOf` method', function() {
10331 function Empty() {}
10332 Empty.prototype.indexOf = R.always(-1);
10333 function List(head, tail) {
10334 this.head = head;
10335 this.tail = tail;
10336 }
10337 List.prototype.indexOf = function(x) {
10338 var idx = this.tail.indexOf(x);
10339 return this.head === x ? 0 : idx >= 0 ? 1 + idx : -1;
10340 };
10341 var list = new List('b',
10342 new List('a',
10343 new List('n',
10344 new List('a',
10345 new List('n',
10346 new List('a',
10347 new Empty()
10348 )
10349 )
10350 )
10351 )
10352 )
10353 );
10354 eq(R.indexOf('a', 'banana'), 1);
10355 eq(R.indexOf('x', 'banana'), -1);
10356 eq(R.indexOf('a', list), 1);
10357 eq(R.indexOf('x', list), -1);
10358 });
10359});
10360```
10361
10362</details>
10363
10364[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#indexOf)
10365
10366### init
10367
10368```typescript
10369
10370init<T>(input: readonly T[]): T[]
10371```
10372
10373It returns all but the last element of list or string `input`.
10374
10375```javascript
10376const result = [
10377 R.init([1, 2, 3]) ,
10378 R.init('foo') // => 'fo'
10379]
10380// => [[1, 2], 'fo']
10381```
10382
10383<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.init(%5B1%2C%202%2C%203%5D)%20%2C%20%0A%20%20R.init('foo')%20%20%2F%2F%20%3D%3E%20'fo'%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%202%5D%2C%20'fo'%5D">Try this <strong>R.init</strong> example in Rambda REPL</a>
10384
10385<details>
10386
10387<summary>All Typescript definitions</summary>
10388
10389```typescript
10390init<T>(input: readonly T[]): T[];
10391init(input: string): string;
10392```
10393
10394</details>
10395
10396<details>
10397
10398<summary><strong>R.init</strong> source</summary>
10399
10400```javascript
10401import baseSlice from './_internals/baseSlice'
10402
10403export function init(listOrString){
10404 if (typeof listOrString === 'string') return listOrString.slice(0, -1)
10405
10406 return listOrString.length ? baseSlice(
10407 listOrString, 0, -1
10408 ) : []
10409}
10410```
10411
10412</details>
10413
10414<details>
10415
10416<summary><strong>Tests</strong></summary>
10417
10418```javascript
10419import { init } from './init'
10420
10421test('with array', () => {
10422 expect(init([ 1, 2, 3 ])).toEqual([ 1, 2 ])
10423 expect(init([ 1, 2 ])).toEqual([ 1 ])
10424 expect(init([ 1 ])).toEqual([])
10425 expect(init([])).toEqual([])
10426 expect(init([])).toEqual([])
10427 expect(init([ 1 ])).toEqual([])
10428})
10429
10430test('with string', () => {
10431 expect(init('foo')).toEqual('fo')
10432 expect(init('f')).toEqual('')
10433 expect(init('')).toEqual('')
10434})
10435```
10436
10437</details>
10438
10439<details>
10440
10441<summary><strong>Typescript</strong> test</summary>
10442
10443```typescript
10444import {init} from 'rambda'
10445
10446describe('R.init', () => {
10447 it('with string', () => {
10448 const result = init('foo')
10449
10450 result // $ExpectType string
10451 })
10452 it('with list', () => {
10453 const result = init([1, 2, 3])
10454
10455 result // $ExpectType number[]
10456 })
10457})
10458```
10459
10460</details>
10461
10462[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#init)
10463
10464### intersection
10465
10466```typescript
10467
10468intersection<T>(listA: readonly T[], listB: readonly T[]): T[]
10469```
10470
10471It loops throw `listA` and `listB` and returns the intersection of the two according to `R.equals`.
10472
10473```javascript
10474const listA = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
10475const listB = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
10476
10477const result = intersection(listA, listB)
10478// => [{ id : 3 }, { id : 4 }]
10479```
10480
10481<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20listA%20%3D%20%5B%20%7B%20id%20%3A%201%20%7D%2C%20%7B%20id%20%3A%202%20%7D%2C%20%7B%20id%20%3A%203%20%7D%2C%20%7B%20id%20%3A%204%20%7D%20%5D%0Aconst%20listB%20%3D%20%5B%20%7B%20id%20%3A%203%20%7D%2C%20%7B%20id%20%3A%204%20%7D%2C%20%7B%20id%20%3A%205%20%7D%2C%20%7B%20id%20%3A%206%20%7D%20%5D%0A%0Aconst%20result%20%3D%20intersection(listA%2C%20listB)%0A%2F%2F%20%3D%3E%20%5B%7B%20id%20%3A%203%20%7D%2C%20%7B%20id%20%3A%204%20%7D%5D">Try this <strong>R.intersection</strong> example in Rambda REPL</a>
10482
10483<details>
10484
10485<summary>All Typescript definitions</summary>
10486
10487```typescript
10488intersection<T>(listA: readonly T[], listB: readonly T[]): T[];
10489intersection<T>(listA: readonly T[]): (listB: readonly T[]) => T[];
10490```
10491
10492</details>
10493
10494<details>
10495
10496<summary><strong>R.intersection</strong> source</summary>
10497
10498```javascript
10499import { filter } from './filter'
10500import { includes } from './includes'
10501
10502export function intersection(listA, listB){
10503 if (arguments.length === 1) return _list => intersection(listA, _list)
10504
10505 return filter(value => includes(value, listB), listA)
10506}
10507```
10508
10509</details>
10510
10511<details>
10512
10513<summary><strong>Tests</strong></summary>
10514
10515```javascript
10516import { intersection } from './intersection'
10517
10518test('intersection', () => {
10519 const list1 = [ 1, 2, 3, 4 ]
10520 const list2 = [ 3, 4, 5, 6 ]
10521 expect(intersection(list1)(list2)).toEqual([ 3, 4 ])
10522
10523 expect(intersection([], [])).toEqual([])
10524})
10525
10526test('intersection with objects', () => {
10527 const list1 = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
10528 const list2 = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
10529 expect(intersection(list1)(list2)).toEqual([ { id : 3 }, { id : 4 } ])
10530})
10531```
10532
10533</details>
10534
10535<details>
10536
10537<summary><strong>Typescript</strong> test</summary>
10538
10539```typescript
10540import {intersection} from 'rambda'
10541
10542const list1 = [1, 2, 3]
10543const list2 = [1, 3, 5]
10544
10545describe('R.intersection', () => {
10546 it('happy', () => {
10547 const result = intersection(list1, list2)
10548 result // $ExpectType number[]
10549
10550 const curriedResult = intersection(list1)(list2)
10551 curriedResult // $ExpectType number[]
10552 })
10553})
10554```
10555
10556</details>
10557
10558[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#intersection)
10559
10560### intersperse
10561
10562```typescript
10563
10564intersperse<T>(separator: T, list: readonly T[]): T[]
10565```
10566
10567It adds a `separator` between members of `list`.
10568
10569```javascript
10570const list = [ 0, 1, 2, 3 ]
10571const separator = '|'
10572const result = intersperse(separator, list)
10573// => [0, '|', 1, '|', 2, '|', 3]
10574```
10575
10576<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%200%2C%201%2C%202%2C%203%20%5D%0Aconst%20separator%20%3D%20'%7C'%0Aconst%20result%20%3D%20intersperse(separator%2C%20list)%0A%2F%2F%20%3D%3E%20%5B0%2C%20'%7C'%2C%201%2C%20'%7C'%2C%202%2C%20'%7C'%2C%203%5D">Try this <strong>R.intersperse</strong> example in Rambda REPL</a>
10577
10578<details>
10579
10580<summary>All Typescript definitions</summary>
10581
10582```typescript
10583intersperse<T>(separator: T, list: readonly T[]): T[];
10584intersperse<T>(separator: T): (list: readonly T[]) => T[];
10585```
10586
10587</details>
10588
10589<details>
10590
10591<summary><strong>R.intersperse</strong> source</summary>
10592
10593```javascript
10594export function intersperse(separator, list){
10595 if (arguments.length === 1) return _list => intersperse(separator, _list)
10596
10597 let index = -1
10598 const len = list.length
10599 const willReturn = []
10600
10601 while (++index < len){
10602 if (index === len - 1){
10603 willReturn.push(list[ index ])
10604 } else {
10605 willReturn.push(list[ index ], separator)
10606 }
10607 }
10608
10609 return willReturn
10610}
10611```
10612
10613</details>
10614
10615<details>
10616
10617<summary><strong>Tests</strong></summary>
10618
10619```javascript
10620import { intersperse } from './intersperse'
10621
10622test('intersperse', () => {
10623 const list = [ { id : 1 }, { id : 2 }, { id : 10 }, { id : 'a' } ]
10624 expect(intersperse('!', list)).toEqual([
10625 { id : 1 },
10626 '!',
10627 { id : 2 },
10628 '!',
10629 { id : 10 },
10630 '!',
10631 { id : 'a' },
10632 ])
10633
10634 expect(intersperse('!')([])).toEqual([])
10635})
10636```
10637
10638</details>
10639
10640<details>
10641
10642<summary><strong>Typescript</strong> test</summary>
10643
10644```typescript
10645import {intersperse} from 'rambda'
10646
10647describe('R.intersperse', () => {
10648 it('happy', () => {
10649 const result = intersperse(1, [1, 2, 3])
10650 result // $ExpectType number[]
10651 })
10652 it('curried', () => {
10653 const result = intersperse('|')(['foo', 'bar'])
10654 result // $ExpectType string[]
10655 })
10656})
10657```
10658
10659</details>
10660
10661[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#intersperse)
10662
10663### is
10664
10665```typescript
10666
10667is(targetPrototype: any, x: any): boolean
10668```
10669
10670It returns `true` if `x` is instance of `targetPrototype`.
10671
10672```javascript
10673const result = [
10674 R.is(String, 'foo'),
10675 R.is(Array, 1)
10676]
10677// => [true, false]
10678```
10679
10680<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.is(String%2C%20'foo')%2C%20%20%0A%20%20R.is(Array%2C%201)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.is</strong> example in Rambda REPL</a>
10681
10682<details>
10683
10684<summary>All Typescript definitions</summary>
10685
10686```typescript
10687is(targetPrototype: any, x: any): boolean;
10688is(targetPrototype: any): (x: any) => boolean;
10689```
10690
10691</details>
10692
10693<details>
10694
10695<summary><strong>R.is</strong> source</summary>
10696
10697```javascript
10698export function is(targetPrototype, x){
10699 if (arguments.length === 1) return _x => is(targetPrototype, _x)
10700
10701 return (
10702 x != null && x.constructor === targetPrototype ||
10703 x instanceof targetPrototype
10704 )
10705}
10706```
10707
10708</details>
10709
10710<details>
10711
10712<summary><strong>Tests</strong></summary>
10713
10714```javascript
10715import { is } from './is'
10716
10717test('works with built-in types', () => {
10718 expect(is(Array, undefined)).toBeFalse()
10719 expect(is(Array)([])).toBeTrue()
10720 expect(is(Boolean, new Boolean(false))).toBeTrue()
10721 expect(is(Date, new Date())).toBeTrue()
10722 expect(is(Function, () => {})).toBeTrue()
10723 expect(is(Number, new Number(0))).toBeTrue()
10724 expect(is(Object, {})).toBeTrue()
10725 expect(is(RegExp, /(?:)/)).toBeTrue()
10726 expect(is(String, new String(''))).toBeTrue()
10727})
10728
10729test('works with user-defined types', () => {
10730 function Foo(){}
10731 function Bar(){}
10732 Bar.prototype = new Foo()
10733
10734 const foo = new Foo()
10735 const bar = new Bar()
10736
10737 expect(is(Foo, foo)).toBeTrue()
10738 expect(is(Bar, bar)).toBeTrue()
10739 expect(is(Foo, bar)).toBeTrue()
10740 expect(is(Bar, foo)).toBeFalse()
10741})
10742
10743test('does not coerce', () => {
10744 expect(is(Boolean, 1)).toBeFalse()
10745 expect(is(Number, '1')).toBeFalse()
10746 expect(is(Number, false)).toBeFalse()
10747})
10748
10749test('recognizes primitives as their object equivalents', () => {
10750 expect(is(Boolean, false)).toBeTrue()
10751 expect(is(Number, 0)).toBeTrue()
10752 expect(is(String, '')).toBeTrue()
10753})
10754
10755test('does not consider primitives to be instances of Object', () => {
10756 expect(is(Object, false)).toBeFalse()
10757 expect(is(Object, 0)).toBeFalse()
10758 expect(is(Object, '')).toBeFalse()
10759})
10760```
10761
10762</details>
10763
10764<details>
10765
10766<summary><strong>Typescript</strong> test</summary>
10767
10768```typescript
10769import {is} from 'rambda'
10770
10771describe('R.is', () => {
10772 it('happy', () => {
10773 const result = is(String, 'foo')
10774 result // $ExpectType boolean
10775 })
10776 it('curried', () => {
10777 const result = is(Number)(1)
10778 result // $ExpectType boolean
10779 })
10780})
10781```
10782
10783</details>
10784
10785[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#is)
10786
10787### isEmpty
10788
10789```typescript
10790
10791isEmpty<T>(x: T): boolean
10792```
10793
10794It returns `true` if `x` is `empty`.
10795
10796```javascript
10797const result = [
10798 R.isEmpty(''),
10799 R.isEmpty({ x : 0 })
10800]
10801// => [true, false]
10802```
10803
10804<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.isEmpty('')%2C%0A%20%20R.isEmpty(%7B%20x%20%3A%200%20%7D)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.isEmpty</strong> example in Rambda REPL</a>
10805
10806<details>
10807
10808<summary>All Typescript definitions</summary>
10809
10810```typescript
10811isEmpty<T>(x: T): boolean;
10812```
10813
10814</details>
10815
10816<details>
10817
10818<summary><strong>R.isEmpty</strong> source</summary>
10819
10820```javascript
10821import { type } from './type'
10822
10823export function isEmpty(input){
10824 const inputType = type(input)
10825 if ([ 'Undefined', 'NaN', 'Number', 'Null' ].includes(inputType))
10826 return false
10827 if (!input) return true
10828
10829 if (inputType === 'Object'){
10830 return Object.keys(input).length === 0
10831 }
10832
10833 if (inputType === 'Array'){
10834 return input.length === 0
10835 }
10836
10837 return false
10838}
10839```
10840
10841</details>
10842
10843<details>
10844
10845<summary><strong>Tests</strong></summary>
10846
10847```javascript
10848import { isEmpty } from './isEmpty'
10849
10850test('happy', () => {
10851 expect(isEmpty(undefined)).toEqual(false)
10852 expect(isEmpty('')).toEqual(true)
10853 expect(isEmpty(null)).toEqual(false)
10854 expect(isEmpty(' ')).toEqual(false)
10855 expect(isEmpty(new RegExp(''))).toEqual(false)
10856 expect(isEmpty([])).toEqual(true)
10857 expect(isEmpty([ [] ])).toEqual(false)
10858 expect(isEmpty({})).toEqual(true)
10859 expect(isEmpty({ x : 0 })).toEqual(false)
10860 expect(isEmpty(0)).toEqual(false)
10861 expect(isEmpty(NaN)).toEqual(false)
10862 expect(isEmpty([ '' ])).toEqual(false)
10863})
10864```
10865
10866</details>
10867
10868<details>
10869
10870<summary><strong>Typescript</strong> test</summary>
10871
10872```typescript
10873import {isEmpty} from 'rambda'
10874
10875describe('R.isEmpty', () => {
10876 it('happy', () => {
10877 const result = isEmpty('foo')
10878 result // $ExpectType boolean
10879 })
10880})
10881```
10882
10883</details>
10884
10885<details>
10886
10887<summary>1 failed <italic>Ramda.isEmpty</italic> specs
10888
10889> :boom: Reason for the failure: Ramda method supports typed arrays
10890</summary>
10891
10892```javascript
10893var R = require('../../../../dist/rambda.js');
10894var eq = require('./shared/eq');
10895
10896describe('isEmpty', function() {
10897 it('returns true for empty typed array', function() {
10898 eq(R.isEmpty(Uint8Array.from('')), true);
10899 eq(R.isEmpty(Float32Array.from('')), true);
10900 eq(R.isEmpty(new Float32Array([])), true);
10901 eq(R.isEmpty(Uint8Array.from('1')), false);
10902 eq(R.isEmpty(Float32Array.from('1')), false);
10903 eq(R.isEmpty(new Float32Array([1])), false);
10904 });
10905});
10906```
10907
10908</details>
10909
10910[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#isEmpty)
10911
10912### isNil
10913
10914```typescript
10915
10916isNil(x: any): x is null | undefined
10917```
10918
10919It returns `true` if `x` is either `null` or `undefined`.
10920
10921```javascript
10922const result = [
10923 R.isNil(null),
10924 R.isNil(1),
10925]
10926// => [true, false]
10927```
10928
10929<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.isNil(null)%2C%0A%20%20R.isNil(1)%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.isNil</strong> example in Rambda REPL</a>
10930
10931<details>
10932
10933<summary>All Typescript definitions</summary>
10934
10935```typescript
10936isNil(x: any): x is null | undefined;
10937```
10938
10939</details>
10940
10941<details>
10942
10943<summary><strong>R.isNil</strong> source</summary>
10944
10945```javascript
10946export function isNil(x){
10947 return x === undefined || x === null
10948}
10949```
10950
10951</details>
10952
10953<details>
10954
10955<summary><strong>Tests</strong></summary>
10956
10957```javascript
10958import { isNil } from './isNil'
10959
10960test('happy', () => {
10961 expect(isNil(null)).toBeTrue()
10962
10963 expect(isNil(undefined)).toBeTrue()
10964
10965 expect(isNil([])).toBeFalse()
10966})
10967```
10968
10969</details>
10970
10971[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#isNil)
10972
10973### join
10974
10975```typescript
10976
10977join<T>(glue: string, list: readonly T[]): string
10978```
10979
10980It returns a string of all `list` instances joined with a `glue`.
10981
10982```javascript
10983R.join('-', [1, 2, 3]) // => '1-2-3'
10984```
10985
10986<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.join('-'%2C%20%5B1%2C%202%2C%203%5D)%20%20%2F%2F%20%3D%3E%20'1-2-3'">Try this <strong>R.join</strong> example in Rambda REPL</a>
10987
10988<details>
10989
10990<summary>All Typescript definitions</summary>
10991
10992```typescript
10993join<T>(glue: string, list: readonly T[]): string;
10994join<T>(glue: string): (list: readonly T[]) => string;
10995```
10996
10997</details>
10998
10999<details>
11000
11001<summary><strong>R.join</strong> source</summary>
11002
11003```javascript
11004export function join(glue, list){
11005 if (arguments.length === 1) return _list => join(glue, _list)
11006
11007 return list.join(glue)
11008}
11009```
11010
11011</details>
11012
11013<details>
11014
11015<summary><strong>Tests</strong></summary>
11016
11017```javascript
11018import { join } from './join'
11019
11020test('curry', () => {
11021 expect(join('|')([ 'foo', 'bar', 'baz' ])).toEqual('foo|bar|baz')
11022
11023 expect(join('|', [ 1, 2, 3 ])).toEqual('1|2|3')
11024
11025 const spacer = join(' ')
11026
11027 expect(spacer([ 'a', 2, 3.4 ])).toEqual('a 2 3.4')
11028})
11029```
11030
11031</details>
11032
11033<details>
11034
11035<summary><strong>Typescript</strong> test</summary>
11036
11037```typescript
11038import {join} from 'rambda'
11039
11040describe('R.join', () => {
11041 it('happy', () => {
11042 const result = join('|', [1, 2, 3])
11043 result // $ExpectType string
11044 })
11045})
11046```
11047
11048</details>
11049
11050[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#join)
11051
11052### keys
11053
11054```typescript
11055
11056keys<T extends object>(x: T): (keyof T)[]
11057```
11058
11059It applies `Object.keys` over `x` and returns its keys.
11060
11061```javascript
11062R.keys({a:1, b:2}) // => ['a', 'b']
11063```
11064
11065<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.keys(%7Ba%3A1%2C%20b%3A2%7D)%20%20%2F%2F%20%3D%3E%20%5B'a'%2C%20'b'%5D">Try this <strong>R.keys</strong> example in Rambda REPL</a>
11066
11067<details>
11068
11069<summary>All Typescript definitions</summary>
11070
11071```typescript
11072keys<T extends object>(x: T): (keyof T)[];
11073keys<T>(x: T): string[];
11074```
11075
11076</details>
11077
11078<details>
11079
11080<summary><strong>R.keys</strong> source</summary>
11081
11082```javascript
11083export function keys(x){
11084 return Object.keys(x)
11085}
11086```
11087
11088</details>
11089
11090<details>
11091
11092<summary><strong>Tests</strong></summary>
11093
11094```javascript
11095import { keys } from './keys'
11096
11097test('happy', () => {
11098 expect(keys({ a : 1 })).toEqual([ 'a' ])
11099})
11100```
11101
11102</details>
11103
11104<details>
11105
11106<summary><strong>Typescript</strong> test</summary>
11107
11108```typescript
11109import {keys} from 'rambda'
11110
11111const obj = {a: 1, b: 2}
11112
11113describe('R.keys', () => {
11114 it('happy', () => {
11115 const result = keys(obj)
11116 result // $ExpectType ("b" | "a")[]
11117 })
11118})
11119```
11120
11121</details>
11122
11123<details>
11124
11125<summary>1 failed <italic>Ramda.keys</italic> specs
11126
11127> :boom: Reason for the failure: Ramda method works for primitives
11128</summary>
11129
11130```javascript
11131var R = require('../../../../dist/rambda.js');
11132var eq = require('./shared/eq');
11133
11134describe('keys', function() {
11135 var obj = {a: 100, b: [1, 2, 3], c: {x: 200, y: 300}, d: 'D', e: null, f: undefined};
11136 function C() { this.a = 100; this.b = 200; }
11137 C.prototype.x = function() { return 'x'; };
11138 C.prototype.y = 'y';
11139 var cobj = new C();
11140 it('works for primitives', function() {
11141 eq(R.keys(null), []);
11142 eq(R.keys(undefined), []);
11143 eq(R.keys(55), []);
11144 eq(R.keys('foo'), []);
11145 eq(R.keys(true), []);
11146 eq(R.keys(false), []);
11147 eq(R.keys(NaN), []);
11148 eq(R.keys(Infinity), []);
11149 eq(R.keys([]), []);
11150 });
11151});
11152```
11153
11154</details>
11155
11156[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#keys)
11157
11158### last
11159
11160```typescript
11161
11162last(str: string): string
11163```
11164
11165It returns the last element of `input`, as the `input` can be either a string or an array.
11166
11167```javascript
11168const result = [
11169 R.last([1, 2, 3]),
11170 R.last('foo'),
11171]
11172// => [3, 'o']
11173```
11174
11175<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.last(%5B1%2C%202%2C%203%5D)%2C%0A%20%20R.last('foo')%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B3%2C%20'o'%5D">Try this <strong>R.last</strong> example in Rambda REPL</a>
11176
11177<details>
11178
11179<summary>All Typescript definitions</summary>
11180
11181```typescript
11182last(str: string): string;
11183last(emptyList: []): undefined;
11184last<T extends any>(list: readonly T[]): T | undefined;
11185```
11186
11187</details>
11188
11189<details>
11190
11191<summary><strong>R.last</strong> source</summary>
11192
11193```javascript
11194export function last(listOrString){
11195 if (typeof listOrString === 'string'){
11196 return listOrString[ listOrString.length - 1 ] || ''
11197 }
11198
11199 return listOrString[ listOrString.length - 1 ]
11200}
11201```
11202
11203</details>
11204
11205<details>
11206
11207<summary><strong>Tests</strong></summary>
11208
11209```javascript
11210import { last } from './last'
11211
11212test('happy', () => {
11213 expect(last([ 'foo', 'bar', 'baz' ])).toEqual('baz')
11214 expect(last([])).toEqual(undefined)
11215 expect(last('abc')).toEqual('c')
11216 expect(last('')).toEqual('')
11217})
11218```
11219
11220</details>
11221
11222<details>
11223
11224<summary><strong>Typescript</strong> test</summary>
11225
11226```typescript
11227import {last} from 'rambda'
11228
11229describe('R.last', () => {
11230 it('string', () => {
11231 const result = last('foo')
11232 result // $ExpectType string
11233 })
11234
11235 it('array', () => {
11236 const result = last([1, 2, 3])
11237 result // $ExpectType number | undefined
11238 })
11239
11240 it('empty array', () => {
11241 const result = last([])
11242 result // $ExpectType undefined
11243 })
11244})
11245```
11246
11247</details>
11248
11249[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#last)
11250
11251### lastIndexOf
11252
11253```typescript
11254
11255lastIndexOf<T>(target: T, list: readonly T[]): number
11256```
11257
11258It returns the last index of `target` in `list` array.
11259
11260`R.equals` is used to determine equality between `target` and members of `list`.
11261
11262If there is no such index, then `-1` is returned.
11263
11264```javascript
11265const list = [1, 2, 3, 1, 2, 3]
11266const result = [
11267 R.lastIndexOf(2, list),
11268 R.lastIndexOf(4, list),
11269]
11270// => [4, -1]
11271```
11272
11273<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%2C%201%2C%202%2C%203%5D%0Aconst%20result%20%3D%20%5B%0A%20%20R.lastIndexOf(2%2C%20list)%2C%0A%20%20R.lastIndexOf(4%2C%20list)%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B4%2C%20-1%5D">Try this <strong>R.lastIndexOf</strong> example in Rambda REPL</a>
11274
11275<details>
11276
11277<summary>All Typescript definitions</summary>
11278
11279```typescript
11280lastIndexOf<T>(target: T, list: readonly T[]): number;
11281lastIndexOf<T>(target: T): (list: readonly T[]) => number;
11282```
11283
11284</details>
11285
11286<details>
11287
11288<summary><strong>R.lastIndexOf</strong> source</summary>
11289
11290```javascript
11291import { equals } from './equals'
11292
11293export function lastIndexOf(target, list){
11294 if (arguments.length === 1) return _list => lastIndexOf(target, _list)
11295
11296 let index = list.length
11297
11298 while (--index > 0){
11299 if (equals(list[ index ], target)){
11300 return index
11301 }
11302 }
11303
11304 return -1
11305}
11306```
11307
11308</details>
11309
11310<details>
11311
11312<summary><strong>Tests</strong></summary>
11313
11314```javascript
11315import { lastIndexOf } from './lastIndexOf'
11316
11317test('happy', () => {
11318 const a = lastIndexOf(1, [ 1, 2, 3, 1, 2 ])
11319 const b = lastIndexOf(1)([ 1, 2, 3, 1, 2 ])
11320
11321 expect(a).toEqual(3)
11322 expect(b).toEqual(3)
11323})
11324
11325test('false', () => {
11326 const a = lastIndexOf(10, [ 1, 2, 3, 1, 2 ])
11327
11328 expect(a).toEqual(-1)
11329})
11330```
11331
11332</details>
11333
11334<details>
11335
11336<summary><strong>Typescript</strong> test</summary>
11337
11338```typescript
11339import {lastIndexOf} from 'rambda'
11340
11341const list = [1, 2, 3]
11342
11343describe('R.lastIndexOf', () => {
11344 it('happy', () => {
11345 const result = lastIndexOf(2, list)
11346 result // $ExpectType number
11347 })
11348 it('curried', () => {
11349 const result = lastIndexOf(2)(list)
11350 result // $ExpectType number
11351 })
11352})
11353```
11354
11355</details>
11356
11357<details>
11358
11359<summary>3 failed <italic>Ramda.lastIndexOf</italic> specs
11360
11361> :boom: Reason for the failure: Ramda method dispatches to `lastIndexOf` method
11362</summary>
11363
11364```javascript
11365var R = require('../../../../dist/rambda.js');
11366var eq = require('./shared/eq');
11367
11368describe('lastIndexOf', function() {
11369 var input = [1, 2, 3, 4, 5, 1];
11370 var list = ['a', 1, 'a'];
11371 list[-2] = 'a'; // Throw a wrench in the gears by assigning a non-valid array index as object property.
11372 it('has R.equals semantics', function() {
11373 function Just(x) { this.value = x; }
11374 Just.prototype.equals = function(x) {
11375 return x instanceof Just && R.equals(x.value, this.value);
11376 };
11377 eq(R.lastIndexOf(0, [-0]), -1);
11378 eq(R.lastIndexOf(-0, [0]), -1);
11379 eq(R.lastIndexOf(NaN, [NaN]), 0);
11380 eq(R.lastIndexOf(new Just([42]), [new Just([42])]), 0);
11381 });
11382 it('dispatches to `lastIndexOf` method', function() {
11383 function Empty() {}
11384 Empty.prototype.lastIndexOf = R.always(-1);
11385 function List(head, tail) {
11386 this.head = head;
11387 this.tail = tail;
11388 }
11389 List.prototype.lastIndexOf = function(x) {
11390 var idx = this.tail.lastIndexOf(x);
11391 return idx >= 0 ? 1 + idx : this.head === x ? 0 : -1;
11392 };
11393 var list = new List('b',
11394 new List('a',
11395 new List('n',
11396 new List('a',
11397 new List('n',
11398 new List('a',
11399 new Empty()
11400 )
11401 )
11402 )
11403 )
11404 )
11405 );
11406 eq(R.lastIndexOf('a', 'banana'), 5);
11407 eq(R.lastIndexOf('x', 'banana'), -1);
11408 eq(R.lastIndexOf('a', list), 5);
11409 eq(R.lastIndexOf('x', list), -1);
11410 });
11411 it('finds function, compared by identity', function() {
11412 var f = function() {};
11413 var g = function() {};
11414 var list = [g, f, g, f];
11415 eq(R.lastIndexOf(f, list), 3);
11416 });
11417});
11418```
11419
11420</details>
11421
11422[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#lastIndexOf)
11423
11424### length
11425
11426```typescript
11427
11428length<T>(input: readonly T[]): number
11429```
11430
11431It returns the `length` property of list or string `input`.
11432
11433```javascript
11434const result = [
11435 R.length([1, 2, 3, 4]),
11436 R.length('foo'),
11437]
11438// => [4, 3]
11439```
11440
11441<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.length(%5B1%2C%202%2C%203%2C%204%5D)%2C%0A%20%20R.length('foo')%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B4%2C%203%5D">Try this <strong>R.length</strong> example in Rambda REPL</a>
11442
11443<details>
11444
11445<summary>All Typescript definitions</summary>
11446
11447```typescript
11448length<T>(input: readonly T[]): number;
11449```
11450
11451</details>
11452
11453<details>
11454
11455<summary><strong>R.length</strong> source</summary>
11456
11457```javascript
11458export function length(x){
11459 if (!x && x !== '' || x.length === undefined){
11460 return NaN
11461 }
11462
11463 return x.length
11464}
11465```
11466
11467</details>
11468
11469<details>
11470
11471<summary><strong>Tests</strong></summary>
11472
11473```javascript
11474import { length } from './length'
11475
11476test('happy', () => {
11477 expect(length('foo')).toEqual(3)
11478 expect(length([ 1, 2, 3 ])).toEqual(3)
11479 expect(length([])).toEqual(0)
11480})
11481
11482test('with empty string', () => {
11483 expect(length('')).toEqual(0)
11484})
11485
11486test('with bad input returns NaN', () => {
11487 expect(length(0)).toBeNaN()
11488 expect(length({})).toBeNaN()
11489 expect(length(null)).toBeNaN()
11490 expect(length(undefined)).toBeNaN()
11491})
11492```
11493
11494</details>
11495
11496<details>
11497
11498<summary>1 failed <italic>Ramda.length</italic> specs
11499
11500> :boom: Reason for the failure: Ramda method supports object with `length` method
11501</summary>
11502
11503```javascript
11504var R = require('../../../../dist/rambda.js');
11505var eq = require('./shared/eq');
11506
11507describe('length', function() {
11508 it('returns the length of a string', function() {
11509 eq(R.length(''), 0);
11510 eq(R.length('xyz'), 3);
11511 });
11512 it('returns NaN for length property of unexpected type', function() {
11513 eq(R.identical(NaN, R.length({length: ''})), true);
11514 eq(R.identical(NaN, R.length({length: '1.23'})), true);
11515 eq(R.identical(NaN, R.length({length: null})), true);
11516 eq(R.identical(NaN, R.length({length: undefined})), true);
11517 eq(R.identical(NaN, R.length({})), true);
11518 });
11519});
11520```
11521
11522</details>
11523
11524[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#length)
11525
11526### lens
11527
11528```typescript
11529
11530lens<T, U, V>(getter: (s: T) => U, setter: (a: U, s: T) => V): Lens
11531```
11532
11533It returns a `lens` for the given `getter` and `setter` functions.
11534
11535The `getter` **gets** the value of the focus; the `setter` **sets** the value of the focus.
11536
11537The setter should not mutate the data structure.
11538
11539```javascript
11540const xLens = R.lens(R.prop('x'), R.assoc('x'));
11541
11542R.view(xLens, {x: 1, y: 2}) // => 1
11543R.set(xLens, 4, {x: 1, y: 2}) // => {x: 4, y: 2}
11544R.over(xLens, R.negate, {x: 1, y: 2}) // => {x: -1, y: 2}
11545```
11546
11547<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20xLens%20%3D%20R.lens(R.prop('x')%2C%20R.assoc('x'))%3B%0A%0AR.view(xLens%2C%20%7Bx%3A%201%2C%20y%3A%202%7D)%20%2F%2F%20%3D%3E%201%0AR.set(xLens%2C%204%2C%20%7Bx%3A%201%2C%20y%3A%202%7D)%20%2F%2F%20%3D%3E%20%7Bx%3A%204%2C%20y%3A%202%7D%0AR.over(xLens%2C%20R.negate%2C%20%7Bx%3A%201%2C%20y%3A%202%7D)%20%2F%2F%20%3D%3E%20%7Bx%3A%20-1%2C%20y%3A%202%7D">Try this <strong>R.lens</strong> example in Rambda REPL</a>
11548
11549<details>
11550
11551<summary>All Typescript definitions</summary>
11552
11553```typescript
11554lens<T, U, V>(getter: (s: T) => U, setter: (a: U, s: T) => V): Lens;
11555```
11556
11557</details>
11558
11559<details>
11560
11561<summary><strong>R.lens</strong> source</summary>
11562
11563```javascript
11564export function lens(getter, setter){
11565 return function (functor){
11566 return function (target){
11567 return functor(getter(target)).map(focus => setter(focus, target))
11568 }
11569 }
11570}
11571```
11572
11573</details>
11574
11575<details>
11576
11577<summary><strong>Typescript</strong> test</summary>
11578
11579```typescript
11580import {lens, assoc} from 'rambda'
11581
11582interface Input {
11583 foo: string,
11584}
11585
11586describe('R.lens', () => {
11587 it('happy', () => {
11588 const fn = lens<Input, string, string>((x: Input) => {
11589 x.foo // $ExpectType string
11590 return x.foo
11591 }, assoc('name'))
11592 fn // $ExpectType Lens
11593 })
11594})
11595```
11596
11597</details>
11598
11599[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#lens)
11600
11601### lensIndex
11602
11603```typescript
11604
11605lensIndex(index: number): Lens
11606```
11607
11608It returns a lens that focuses on specified `index`.
11609
11610```javascript
11611const list = ['a', 'b', 'c']
11612const headLens = R.lensIndex(0)
11613
11614R.view(headLens, list) // => 'a'
11615R.set(headLens, 'x', list) // => ['x', 'b', 'c']
11616R.over(headLens, R.toUpper, list) // => ['A', 'b', 'c']
11617```
11618
11619<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20list%20%3D%20%5B'a'%2C%20'b'%2C%20'c'%5D%0Aconst%20headLens%20%3D%20R.lensIndex(0)%0A%0AR.view(headLens%2C%20list)%20%2F%2F%20%3D%3E%20'a'%0AR.set(headLens%2C%20'x'%2C%20list)%20%2F%2F%20%3D%3E%20%5B'x'%2C%20'b'%2C%20'c'%5D%0AR.over(headLens%2C%20R.toUpper%2C%20list)%20%2F%2F%20%3D%3E%20%5B'A'%2C%20'b'%2C%20'c'%5D">Try this <strong>R.lensIndex</strong> example in Rambda REPL</a>
11620
11621<details>
11622
11623<summary>All Typescript definitions</summary>
11624
11625```typescript
11626lensIndex(index: number): Lens;
11627```
11628
11629</details>
11630
11631<details>
11632
11633<summary><strong>R.lensIndex</strong> source</summary>
11634
11635```javascript
11636import { lens } from './lens'
11637import { nth } from './nth'
11638import { update } from './update'
11639
11640export function lensIndex(index){
11641 return lens(nth(index), update(index))
11642}
11643```
11644
11645</details>
11646
11647<details>
11648
11649<summary><strong>Tests</strong></summary>
11650
11651```javascript
11652import { compose } from './compose'
11653import { keys } from './keys'
11654import { lensIndex } from './lensIndex'
11655import { over } from './over'
11656import { set } from './set'
11657import { view } from './view'
11658
11659const testList = [ { a : 1 }, { b : 2 }, { c : 3 } ]
11660
11661test('focuses list element at the specified index', () => {
11662 expect(view(lensIndex(0), testList)).toEqual({ a : 1 })
11663})
11664
11665test('returns undefined if the specified index does not exist', () => {
11666 expect(view(lensIndex(10), testList)).toEqual(undefined)
11667})
11668
11669test('sets the list value at the specified index', () => {
11670 expect(set(
11671 lensIndex(0), 0, testList
11672 )).toEqual([ 0, { b : 2 }, { c : 3 } ])
11673})
11674
11675test('applies function to the value at the specified list index', () => {
11676 expect(over(
11677 lensIndex(2), keys, testList
11678 )).toEqual([ { a : 1 }, { b : 2 }, [ 'c' ] ])
11679})
11680
11681test('can be composed', () => {
11682 const nestedList = [ 0, [ 10, 11, 12 ], 1, 2 ]
11683 const composedLens = compose(lensIndex(1), lensIndex(0))
11684
11685 expect(view(composedLens, nestedList)).toEqual(10)
11686})
11687
11688test('set s (get s) === s', () => {
11689 expect(set(
11690 lensIndex(0), view(lensIndex(0), testList), testList
11691 )).toEqual(testList)
11692})
11693
11694test('get (set s v) === v', () => {
11695 expect(view(lensIndex(0), set(
11696 lensIndex(0), 0, testList
11697 ))).toEqual(0)
11698})
11699
11700test('get (set(set s v1) v2) === v2', () => {
11701 expect(view(lensIndex(0),
11702 set(
11703 lensIndex(0), 11, set(
11704 lensIndex(0), 10, testList
11705 )
11706 ))).toEqual(11)
11707})
11708```
11709
11710</details>
11711
11712<details>
11713
11714<summary><strong>Typescript</strong> test</summary>
11715
11716```typescript
11717import {view, lensIndex} from 'rambda'
11718
11719interface Input {
11720 a: number,
11721}
11722const testList: Input[] = [{a: 1}, {a: 2}, {a: 3}]
11723
11724describe('R.lensIndex', () => {
11725 it('happy', () => {
11726 const result = view<Input[], Input>(lensIndex(0), testList)
11727 result // $ExpectType Input
11728 result.a // $ExpectType number
11729 })
11730})
11731```
11732
11733</details>
11734
11735[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#lensIndex)
11736
11737### lensPath
11738
11739```typescript
11740
11741lensPath(path: RamdaPath): Lens
11742```
11743
11744It returns a lens that focuses on specified `path`.
11745
11746```javascript
11747const lensPath = R.lensPath(['x', 0, 'y'])
11748const input = {x: [{y: 2, z: 3}, {y: 4, z: 5}]}
11749
11750R.view(lensPath, input) //=> 2
11751
11752R.set(lensPath, 1, input)
11753//=> {x: [{y: 1, z: 3}, {y: 4, z: 5}]}
11754
11755R.over(xHeadYLens, R.negate, input)
11756//=> {x: [{y: -2, z: 3}, {y: 4, z: 5}]}
11757```
11758
11759<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20lensPath%20%3D%20R.lensPath(%5B'x'%2C%200%2C%20'y'%5D)%0Aconst%20input%20%3D%20%7Bx%3A%20%5B%7By%3A%202%2C%20z%3A%203%7D%2C%20%7By%3A%204%2C%20z%3A%205%7D%5D%7D%0A%0AR.view(lensPath%2C%20input)%20%2F%2F%3D%3E%202%0A%0AR.set(lensPath%2C%201%2C%20input)%20%0A%2F%2F%3D%3E%20%7Bx%3A%20%5B%7By%3A%201%2C%20z%3A%203%7D%2C%20%7By%3A%204%2C%20z%3A%205%7D%5D%7D%0A%0AR.over(xHeadYLens%2C%20R.negate%2C%20input)%20%0A%2F%2F%3D%3E%20%7Bx%3A%20%5B%7By%3A%20-2%2C%20z%3A%203%7D%2C%20%7By%3A%204%2C%20z%3A%205%7D%5D%7D">Try this <strong>R.lensPath</strong> example in Rambda REPL</a>
11760
11761<details>
11762
11763<summary>All Typescript definitions</summary>
11764
11765```typescript
11766lensPath(path: RamdaPath): Lens;
11767lensPath(path: string): Lens;
11768```
11769
11770</details>
11771
11772<details>
11773
11774<summary><strong>R.lensPath</strong> source</summary>
11775
11776```javascript
11777import { assocPath } from './assocPath'
11778import { lens } from './lens'
11779import { path } from './path'
11780
11781export function lensPath(key){
11782 return lens(path(key), assocPath(key))
11783}
11784```
11785
11786</details>
11787
11788<details>
11789
11790<summary><strong>Tests</strong></summary>
11791
11792```javascript
11793import { compose } from './compose'
11794import { identity } from './identity'
11795import { inc } from './inc'
11796import { lensPath } from './lensPath'
11797import { lensProp } from './lensProp'
11798import { over } from './over'
11799import { set } from './set'
11800import { view } from './view'
11801
11802const testObj = {
11803 a : [ { b : 1 }, { b : 2 } ],
11804 d : 3,
11805}
11806
11807test('view', () => {
11808 expect(view(lensPath('d'), testObj)).toEqual(3)
11809 expect(view(lensPath('a.0.b'), testObj)).toEqual(1)
11810 // this is different to ramda, as ramda will return a clone of the input object
11811 expect(view(lensPath(''), testObj)).toEqual(undefined)
11812})
11813
11814test('set', () => {
11815 expect(set(
11816 lensProp('d'), 0, testObj
11817 )).toEqual({
11818 a : [ { b : 1 }, { b : 2 } ],
11819 d : 0,
11820 })
11821 expect(set(
11822 lensPath('a.0.b'), 0, testObj
11823 )).toEqual({
11824 a : [ { b : 0 }, { b : 2 } ],
11825 d : 3,
11826 })
11827 expect(set(
11828 lensPath('a.0.X'), 0, testObj
11829 )).toEqual({
11830 a : [
11831 {
11832 b : 1,
11833 X : 0,
11834 },
11835 { b : 2 },
11836 ],
11837 d : 3,
11838 })
11839 expect(set(
11840 lensPath([]), 0, testObj
11841 )).toEqual(0)
11842})
11843
11844test('over', () => {
11845 expect(over(
11846 lensPath('d'), inc, testObj
11847 )).toEqual({
11848 a : [ { b : 1 }, { b : 2 } ],
11849 d : 4,
11850 })
11851 expect(over(
11852 lensPath('a.1.b'), inc, testObj
11853 )).toEqual({
11854 a : [ { b : 1 }, { b : 3 } ],
11855 d : 3,
11856 })
11857 expect(over(
11858 lensProp('X'), identity, testObj
11859 )).toEqual({
11860 a : [ { b : 1 }, { b : 2 } ],
11861 d : 3,
11862 X : undefined,
11863 })
11864 expect(over(
11865 lensPath('a.0.X'), identity, testObj
11866 )).toEqual({
11867 a : [
11868 {
11869 b : 1,
11870 X : undefined,
11871 },
11872 { b : 2 },
11873 ],
11874 d : 3,
11875 })
11876})
11877
11878test('compose', () => {
11879 const composedLens = compose(lensPath('a'), lensPath('1.b'))
11880 expect(view(composedLens, testObj)).toEqual(2)
11881})
11882
11883test('set s (get s) === s', () => {
11884 expect(set(
11885 lensPath([ 'd' ]), view(lensPath([ 'd' ]), testObj), testObj
11886 )).toEqual(testObj)
11887 expect(set(
11888 lensPath([ 'a', 0, 'b' ]),
11889 view(lensPath([ 'a', 0, 'b' ]), testObj),
11890 testObj
11891 )).toEqual(testObj)
11892})
11893
11894test('get (set s v) === v', () => {
11895 expect(view(lensPath([ 'd' ]), set(
11896 lensPath([ 'd' ]), 0, testObj
11897 ))).toEqual(0)
11898 expect(view(lensPath([ 'a', 0, 'b' ]), set(
11899 lensPath([ 'a', 0, 'b' ]), 0, testObj
11900 ))).toEqual(0)
11901})
11902
11903test('get (set(set s v1) v2) === v2', () => {
11904 const p = [ 'd' ]
11905 const q = [ 'a', 0, 'b' ]
11906 expect(view(lensPath(p), set(
11907 lensPath(p), 11, set(
11908 lensPath(p), 10, testObj
11909 )
11910 ))).toEqual(11)
11911 expect(view(lensPath(q), set(
11912 lensPath(q), 11, set(
11913 lensPath(q), 10, testObj
11914 )
11915 ))).toEqual(11)
11916})
11917```
11918
11919</details>
11920
11921<details>
11922
11923<summary><strong>Typescript</strong> test</summary>
11924
11925```typescript
11926import {lensPath, view} from 'rambda'
11927
11928interface Input {
11929 foo: number[],
11930 bar: {
11931 a: string,
11932 b: string,
11933 },
11934}
11935
11936const testObject: Input = {
11937 foo: [1, 2],
11938 bar: {
11939 a: 'x',
11940 b: 'y',
11941 },
11942}
11943
11944const path = lensPath(['bar', 'a'])
11945const pathAsString = lensPath('bar.a')
11946
11947describe('R.lensPath', () => {
11948 it('happy', () => {
11949 const result = view<Input, string>(path, testObject)
11950 result // $ExpectType string
11951 })
11952 it('using string as path input', () => {
11953 const result = view<Input, string>(pathAsString, testObject)
11954 result // $ExpectType string
11955 })
11956})
11957```
11958
11959</details>
11960
11961[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#lensPath)
11962
11963### lensProp
11964
11965```typescript
11966
11967lensProp(prop: string): {
11968 <T, U>(obj: T): U
11969```
11970
11971It returns a lens that focuses on specified property `prop`.
11972
11973```javascript
11974const xLens = R.lensProp('x');
11975const input = {x: 1, y: 2}
11976
11977R.view(xLens, input) // => 1
11978
11979R.set(xLens, 4, input)
11980// => {x: 4, y: 2}
11981
11982R.over(xLens, R.negate, input)
11983// => {x: -1, y: 2}
11984```
11985
11986<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20xLens%20%3D%20R.lensProp('x')%3B%0Aconst%20input%20%3D%20%7Bx%3A%201%2C%20y%3A%202%7D%0A%0AR.view(xLens%2C%20input)%20%2F%2F%20%3D%3E%201%0A%0AR.set(xLens%2C%204%2C%20input)%20%0A%2F%2F%20%3D%3E%20%7Bx%3A%204%2C%20y%3A%202%7D%0A%0AR.over(xLens%2C%20R.negate%2C%20input)%20%0A%2F%2F%20%3D%3E%20%7Bx%3A%20-1%2C%20y%3A%202%7D">Try this <strong>R.lensProp</strong> example in Rambda REPL</a>
11987
11988<details>
11989
11990<summary>All Typescript definitions</summary>
11991
11992```typescript
11993lensProp(prop: string): {
11994 <T, U>(obj: T): U;
11995 set<T, U, V>(val: T, obj: U): V;
11996};
11997```
11998
11999</details>
12000
12001<details>
12002
12003<summary><strong>R.lensProp</strong> source</summary>
12004
12005```javascript
12006import { assoc } from './assoc'
12007import { lens } from './lens'
12008import { prop } from './prop'
12009
12010export function lensProp(key){
12011 return lens(prop(key), assoc(key))
12012}
12013```
12014
12015</details>
12016
12017<details>
12018
12019<summary><strong>Tests</strong></summary>
12020
12021```javascript
12022import { compose } from './compose'
12023import { identity } from './identity'
12024import { inc } from './inc'
12025import { lensProp } from './lensProp'
12026import { over } from './over'
12027import { set } from './set'
12028import { view } from './view'
12029
12030const testObj = {
12031 a : 1,
12032 b : 2,
12033 c : 3,
12034}
12035
12036test('focuses object the specified object property', () => {
12037 expect(view(lensProp('a'), testObj)).toEqual(1)
12038})
12039
12040test('returns undefined if the specified property does not exist', () => {
12041 expect(view(lensProp('X'), testObj)).toEqual(undefined)
12042})
12043
12044test('sets the value of the object property specified', () => {
12045 expect(set(
12046 lensProp('a'), 0, testObj
12047 )).toEqual({
12048 a : 0,
12049 b : 2,
12050 c : 3,
12051 })
12052})
12053
12054test('adds the property to the object if it doesn\'t exist', () => {
12055 expect(set(
12056 lensProp('d'), 4, testObj
12057 )).toEqual({
12058 a : 1,
12059 b : 2,
12060 c : 3,
12061 d : 4,
12062 })
12063})
12064
12065test('applies function to the value of the specified object property', () => {
12066 expect(over(
12067 lensProp('a'), inc, testObj
12068 )).toEqual({
12069 a : 2,
12070 b : 2,
12071 c : 3,
12072 })
12073})
12074
12075test('applies function to undefined and adds the property if it doesn\'t exist', () => {
12076 expect(over(
12077 lensProp('X'), identity, testObj
12078 )).toEqual({
12079 a : 1,
12080 b : 2,
12081 c : 3,
12082 X : undefined,
12083 })
12084})
12085
12086test('can be composed', () => {
12087 const nestedObj = {
12088 a : { b : 1 },
12089 c : 2,
12090 }
12091 const composedLens = compose(lensProp('a'), lensProp('b'))
12092
12093 expect(view(composedLens, nestedObj)).toEqual(1)
12094})
12095
12096test('set s (get s) === s', () => {
12097 expect(set(
12098 lensProp('a'), view(lensProp('a'), testObj), testObj
12099 )).toEqual(testObj)
12100})
12101
12102test('get (set s v) === v', () => {
12103 expect(view(lensProp('a'), set(
12104 lensProp('a'), 0, testObj
12105 ))).toEqual(0)
12106})
12107
12108test('get (set(set s v1) v2) === v2', () => {
12109 expect(view(lensProp('a'),
12110 set(
12111 lensProp('a'), 11, set(
12112 lensProp('a'), 10, testObj
12113 )
12114 ))).toEqual(11)
12115})
12116```
12117
12118</details>
12119
12120<details>
12121
12122<summary><strong>Typescript</strong> test</summary>
12123
12124```typescript
12125import {lensProp, view} from 'rambda'
12126
12127interface Input {
12128 foo: string,
12129}
12130
12131const testObject: Input = {
12132 foo: 'Led Zeppelin',
12133}
12134
12135const lens = lensProp('foo')
12136
12137describe('R.lensProp', () => {
12138 it('happy', () => {
12139 const result = view<Input, string>(lens, testObject)
12140 result // $ExpectType string
12141 })
12142})
12143```
12144
12145</details>
12146
12147[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#lensProp)
12148
12149### map
12150
12151```typescript
12152
12153map<T, U>(fn: MapFunctionObject<T, U>, iterable: Dictionary<T>): Dictionary<U>
12154```
12155
12156It returns the result of looping through `iterable` with `fn`.
12157
12158It works with both array and object.
12159
12160> :boom: Unlike Ramda's `map`, here property and input object are passed as arguments to `fn`, when `iterable` is an object.
12161
12162```javascript
12163const fn = x => x * 2
12164const fnWhenObject = (val, prop)=>{
12165 return `${prop}-${val}`
12166}
12167
12168const iterable = [1, 2]
12169const obj = {a: 1, b: 2}
12170
12171const result = [
12172 R.map(fn, list),
12173 R.map(fnWhenObject, obj)
12174]
12175// => [ [1, 4], {a: 'a-1', b: 'b-2'}]
12176```
12177
12178<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20x%20%3D%3E%20x%20*%202%0Aconst%20fnWhenObject%20%3D%20(val%2C%20prop)%3D%3E%7B%0A%20%20return%20%60%24%7Bprop%7D-%24%7Bval%7D%60%0A%7D%0A%0Aconst%20iterable%20%3D%20%5B1%2C%202%5D%0Aconst%20obj%20%3D%20%7Ba%3A%201%2C%20b%3A%202%7D%0A%0Aconst%20result%20%3D%20%5B%20%0A%20%20R.map(fn%2C%20list)%2C%0A%20%20R.map(fnWhenObject%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5B%20%5B1%2C%204%5D%2C%20%7Ba%3A%20'a-1'%2C%20b%3A%20'b-2'%7D%5D">Try this <strong>R.map</strong> example in Rambda REPL</a>
12179
12180<details>
12181
12182<summary>All Typescript definitions</summary>
12183
12184```typescript
12185map<T, U>(fn: MapFunctionObject<T, U>, iterable: Dictionary<T>): Dictionary<U>;
12186map<T, U>(fn: MapIterator<T, U>, iterable: readonly T[]): U[];
12187map<T, U>(fn: MapIterator<T, U>): (iterable: readonly T[]) => U[];
12188map<T, U, S>(fn: MapFunctionObject<T, U>): (iterable: Dictionary<T>) => Dictionary<U>;
12189map<T>(fn: MapIterator<T, T>): (iterable: readonly T[]) => T[];
12190map<T>(fn: MapIterator<T, T>, iterable: readonly T[]): T[];
12191```
12192
12193</details>
12194
12195<details>
12196
12197<summary><strong>R.map</strong> source</summary>
12198
12199```javascript
12200import { _isArray } from './_internals/_isArray'
12201import { _keys } from './_internals/_keys'
12202
12203export function mapArray(
12204 fn, list, isIndexed = false
12205){
12206 let index = 0
12207 const willReturn = Array(list.length)
12208
12209 while (index < list.length){
12210 willReturn[ index ] = isIndexed ? fn(list[ index ], index) : fn(list[ index ])
12211
12212 index++
12213 }
12214
12215 return willReturn
12216}
12217
12218export function mapObject(fn, obj){
12219 let index = 0
12220 const keys = _keys(obj)
12221 const len = keys.length
12222 const willReturn = {}
12223
12224 while (index < len){
12225 const key = keys[ index ]
12226 willReturn[ key ] = fn(
12227 obj[ key ], key, obj
12228 )
12229 index++
12230 }
12231
12232 return willReturn
12233}
12234
12235export function map(fn, list){
12236 if (arguments.length === 1) return _list => map(fn, _list)
12237 if (list === undefined) return []
12238 if (_isArray(list)) return mapArray(fn, list)
12239
12240 return mapObject(fn, list)
12241}
12242```
12243
12244</details>
12245
12246<details>
12247
12248<summary><strong>Tests</strong></summary>
12249
12250```javascript
12251import { map } from './map'
12252
12253const double = x => x * 2
12254
12255const sampleObject = {
12256 a : 1,
12257 b : 2,
12258 c : 3,
12259 d : 4,
12260}
12261
12262test('with array', () => {
12263 expect(map(double, [ 1, 2, 3 ])).toEqual([ 2, 4, 6 ])
12264})
12265
12266test('with object', () => {
12267 const obj = {
12268 a : 1,
12269 b : 2,
12270 }
12271
12272 expect(map(double, obj)).toEqual({
12273 a : 2,
12274 b : 4,
12275 })
12276})
12277
12278test('pass input object as third argument', () => {
12279 const obj = {
12280 a : 1,
12281 b : 2,
12282 }
12283 const iterator = (
12284 val, prop, inputObject
12285 ) => {
12286 expect(inputObject).toEqual(obj)
12287
12288 return val * 2
12289 }
12290
12291 expect(map(iterator, obj)).toEqual({
12292 a : 2,
12293 b : 4,
12294 })
12295})
12296
12297test('with object passes property as second argument', () => {
12298 map((_, prop) => {
12299 expect(typeof prop).toEqual('string')
12300 })(sampleObject)
12301})
12302
12303/**
12304 * https://github.com/selfrefactor/rambda/issues/77
12305 */
12306test('when undefined instead of array', () => {
12307 expect(map(double, undefined)).toEqual([])
12308})
12309```
12310
12311</details>
12312
12313<details>
12314
12315<summary><strong>Typescript</strong> test</summary>
12316
12317```typescript
12318import {map} from 'rambda'
12319
12320describe('R.map with arrays', () => {
12321 it('iterable returns the same type as the input', () => {
12322 const result = map<number>(
12323 (x: number) => {
12324 x // $ExpectType number
12325 return x + 2
12326 },
12327 [1, 2, 3]
12328 )
12329 result // $ExpectType number[]
12330 })
12331 it('iterable returns the same type as the input - curried', () => {
12332 const result = map<number>((x: number) => {
12333 x // $ExpectType number
12334 return x + 2
12335 })([1, 2, 3])
12336 result // $ExpectType number[]
12337 })
12338})
12339
12340describe('R.map with objects', () => {
12341 it('iterable with all three arguments - curried', () => {
12342 // It requires dummy third typing argument
12343 // in order to identify compared to curry typings for arrays
12344 // ============================================
12345 const result = map<number, string, any>((a, b, c) => {
12346 a // $ExpectType number
12347 b // $ExpectType string
12348 c // $ExpectType Dictionary<number>
12349 return `${a}`
12350 })({a: 1, b: 2})
12351 result // $ExpectType Dictionary<string>
12352 })
12353 it('iterable with all three arguments', () => {
12354 const result = map<number, string>(
12355 (a, b, c) => {
12356 a // $ExpectType number
12357 b // $ExpectType string
12358 c // $ExpectType Dictionary<number>
12359 return `${a}`
12360 },
12361 {a: 1, b: 2}
12362 )
12363 result // $ExpectType Dictionary<string>
12364 })
12365 it('iterable with property argument', () => {
12366 const result = map<number, string>(
12367 (a, b) => {
12368 a // $ExpectType number
12369 b // $ExpectType string
12370 return `${a}`
12371 },
12372 {a: 1, b: 2}
12373 )
12374 result // $ExpectType Dictionary<string>
12375 })
12376 it('iterable with no property argument', () => {
12377 const result = map<number, string>(
12378 a => {
12379 a // $ExpectType number
12380 return `${a}`
12381 },
12382 {a: 1, b: 2}
12383 )
12384 result // $ExpectType Dictionary<string>
12385 })
12386})
12387```
12388
12389</details>
12390
12391[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#map)
12392
12393### match
12394
12395```typescript
12396
12397match(regExpression: RegExp, str: string): string[]
12398```
12399
12400Curried version of `String.prototype.match` which returns empty array, when there is no match.
12401
12402```javascript
12403const result = [
12404 R.match('a', 'foo'),
12405 R.match(/([a-z]a)/g, 'bananas')
12406]
12407// => [[], ['ba', 'na', 'na']]
12408```
12409
12410<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.match('a'%2C%20'foo')%2C%0A%20%20R.match(%2F(%5Ba-z%5Da)%2Fg%2C%20'bananas')%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B%5D%2C%20%5B'ba'%2C%20'na'%2C%20'na'%5D%5D">Try this <strong>R.match</strong> example in Rambda REPL</a>
12411
12412<details>
12413
12414<summary>All Typescript definitions</summary>
12415
12416```typescript
12417match(regExpression: RegExp, str: string): string[];
12418match(regExpression: RegExp): (str: string) => string[];
12419```
12420
12421</details>
12422
12423<details>
12424
12425<summary><strong>R.match</strong> source</summary>
12426
12427```javascript
12428export function match(pattern, input){
12429 if (arguments.length === 1) return _input => match(pattern, _input)
12430
12431 const willReturn = input.match(pattern)
12432
12433 return willReturn === null ? [] : willReturn
12434}
12435```
12436
12437</details>
12438
12439<details>
12440
12441<summary><strong>Tests</strong></summary>
12442
12443```javascript
12444import { equals } from './equals'
12445import { match } from './match'
12446
12447test('happy', () => {
12448 expect(match(/a./g)('foo bar baz')).toEqual([ 'ar', 'az' ])
12449})
12450
12451test('fallback', () => {
12452 expect(match(/a./g)('foo')).toEqual([])
12453})
12454
12455test('with string', () => {
12456 expect(match('a', 'foo')).toEqual([])
12457 expect(equals(match('o', 'foo'), [ 'o' ])).toBeTrue()
12458})
12459
12460test('throwing', () => {
12461 expect(() => {
12462 match(/a./g, null)
12463 }).toThrowWithMessage(TypeError, 'Cannot read property \'match\' of null')
12464})
12465```
12466
12467</details>
12468
12469<details>
12470
12471<summary><strong>Typescript</strong> test</summary>
12472
12473```typescript
12474import {match} from 'rambda'
12475
12476const str = 'foo bar'
12477
12478describe('R.match', () => {
12479 it('happy', () => {
12480 const result = match(/foo/, str)
12481 result // $ExpectType string[]
12482 })
12483 it('curried', () => {
12484 const result = match(/foo/)(str)
12485 result // $ExpectType string[]
12486 })
12487})
12488```
12489
12490</details>
12491
12492[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#match)
12493
12494### mathMod
12495
12496```typescript
12497
12498mathMod(x: number, y: number): number
12499```
12500
12501`R.mathMod` behaves like the modulo operator should mathematically, unlike the `%` operator (and by extension, `R.modulo`). So while `-17 % 5` is `-2`, `mathMod(-17, 5)` is `3`.
12502
12503> :boom: Explanation is taken from `Ramda` documentation site.
12504
12505```javascript
12506const result = [
12507 R.mathMod(-17, 5),
12508 R.mathMod(17, 5),
12509 R.mathMod(17, -5),
12510 R.mathMod(17, 0)
12511]
12512// => [3, 2, NaN, NaN]
12513```
12514
12515<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.mathMod(-17%2C%205)%2C%0A%20%20R.mathMod(17%2C%205)%2C%0A%20%20R.mathMod(17%2C%20-5)%2C%20%20%0A%20%20R.mathMod(17%2C%200)%20%20%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B3%2C%202%2C%20NaN%2C%20NaN%5D">Try this <strong>R.mathMod</strong> example in Rambda REPL</a>
12516
12517<details>
12518
12519<summary>All Typescript definitions</summary>
12520
12521```typescript
12522mathMod(x: number, y: number): number;
12523mathMod(x: number): (y: number) => number;
12524```
12525
12526</details>
12527
12528<details>
12529
12530<summary><strong>R.mathMod</strong> source</summary>
12531
12532```javascript
12533import _isInteger from './_internals/_isInteger'
12534
12535export function mathMod(x, y){
12536 if (arguments.length === 1) return _y => mathMod(x, _y)
12537 if (!_isInteger(x) || !_isInteger(y) || y < 1) return NaN
12538
12539 return (x % y + y) % y
12540}
12541```
12542
12543</details>
12544
12545<details>
12546
12547<summary><strong>Tests</strong></summary>
12548
12549```javascript
12550import { mathMod } from './mathMod'
12551
12552test('happy', () => {
12553 expect(mathMod(-17)(5)).toEqual(3)
12554 expect(mathMod(17, 5)).toEqual(2)
12555 expect(mathMod(17, -5)).toBeNaN()
12556 expect(mathMod(17, 0)).toBeNaN()
12557 expect(mathMod('17', 5)).toBeNaN()
12558 expect(mathMod({}, 2)).toBeNaN()
12559 expect(mathMod([], 2)).toBeNaN()
12560 expect(mathMod(Symbol(), 2)).toBeNaN()
12561})
12562```
12563
12564</details>
12565
12566<details>
12567
12568<summary><strong>Typescript</strong> test</summary>
12569
12570```typescript
12571import {mathMod} from 'rambda'
12572
12573const first = 1
12574const second = 2
12575
12576describe('R.mathMod', () => {
12577 it('happy', () => {
12578 const result = mathMod(first, second)
12579 result // $ExpectType number
12580 })
12581 it('curried', () => {
12582 const result = mathMod(first, second)
12583 result // $ExpectType number
12584 })
12585})
12586```
12587
12588</details>
12589
12590[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#mathMod)
12591
12592### max
12593
12594```typescript
12595
12596max<T extends Ord>(x: T, y: T): T
12597```
12598
12599It returns the greater value between `x` and `y`.
12600
12601```javascript
12602const result = [
12603 R.max(5, 7),
12604 R.max('bar', 'foo'),
12605]
12606// => [7, 'foo']
12607```
12608
12609<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.max(5%2C%207)%2C%20%20%0A%20%20R.max('bar'%2C%20'foo')%2C%20%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B7%2C%20'foo'%5D">Try this <strong>R.max</strong> example in Rambda REPL</a>
12610
12611<details>
12612
12613<summary>All Typescript definitions</summary>
12614
12615```typescript
12616max<T extends Ord>(x: T, y: T): T;
12617max<T extends Ord>(x: T): (y: T) => T;
12618```
12619
12620</details>
12621
12622<details>
12623
12624<summary><strong>R.max</strong> source</summary>
12625
12626```javascript
12627export function max(x, y){
12628 if (arguments.length === 1) return _y => max(x, _y)
12629
12630 return y > x ? y : x
12631}
12632```
12633
12634</details>
12635
12636<details>
12637
12638<summary><strong>Tests</strong></summary>
12639
12640```javascript
12641import { max } from './max'
12642
12643test('with number', () => {
12644 expect(max(2, 1)).toBe(2)
12645})
12646
12647test('with string', () => {
12648 expect(max('foo')('bar')).toBe('foo')
12649 expect(max('bar')('baz')).toBe('baz')
12650})
12651```
12652
12653</details>
12654
12655<details>
12656
12657<summary><strong>Typescript</strong> test</summary>
12658
12659```typescript
12660import {max} from 'rambda'
12661
12662const first = 1
12663const second = 2
12664
12665describe('R.max', () => {
12666 it('happy', () => {
12667 const result = max(first, second)
12668 result // $ExpectType 1 | 2
12669 })
12670 it('curried', () => {
12671 const result = max(first, second)
12672 result // $ExpectType 1 | 2
12673 })
12674 it('curried - cann pass type', () => {
12675 const result = max<number>(first, second)
12676 result // $ExpectType number
12677 })
12678 it('can pass type', () => {
12679 const result = max<number>(first, second)
12680 result // $ExpectType number
12681 })
12682})
12683```
12684
12685</details>
12686
12687[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#max)
12688
12689### maxBy
12690
12691```typescript
12692
12693maxBy<T>(compareFn: (input: T) => Ord, x: T, y: T): T
12694```
12695
12696It returns the greater value between `x` and `y` according to `compareFn` function.
12697
12698```javascript
12699const compareFn = Math.abs
12700
12701R.maxBy(compareFn, 5, -7) // => -7
12702```
12703
12704<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20compareFn%20%3D%20Math.abs%0A%0AR.maxBy(compareFn%2C%205%2C%20-7)%20%2F%2F%20%3D%3E%20-7">Try this <strong>R.maxBy</strong> example in Rambda REPL</a>
12705
12706<details>
12707
12708<summary>All Typescript definitions</summary>
12709
12710```typescript
12711maxBy<T>(compareFn: (input: T) => Ord, x: T, y: T): T;
12712maxBy<T>(compareFn: (input: T) => Ord, x: T): (y: T) => T;
12713maxBy<T>(compareFn: (input: T) => Ord): FunctionToolbelt.Curry<(x: T, y: T) => T>;
12714```
12715
12716</details>
12717
12718<details>
12719
12720<summary><strong>R.maxBy</strong> source</summary>
12721
12722```javascript
12723import { curry } from './curry'
12724
12725export function maxByFn(
12726 compareFn, x, y
12727){
12728 return compareFn(y) > compareFn(x) ? y : x
12729}
12730
12731export const maxBy = curry(maxByFn)
12732```
12733
12734</details>
12735
12736<details>
12737
12738<summary><strong>Tests</strong></summary>
12739
12740```javascript
12741import { maxBy } from './maxBy'
12742
12743test('happy', () => {
12744 expect(maxBy(
12745 Math.abs, -5, 2
12746 )).toEqual(-5)
12747})
12748
12749test('curried', () => {
12750 expect(maxBy(Math.abs)(2, -5)).toEqual(-5)
12751 expect(maxBy(Math.abs)(2)(-5)).toEqual(-5)
12752})
12753```
12754
12755</details>
12756
12757<details>
12758
12759<summary><strong>Typescript</strong> test</summary>
12760
12761```typescript
12762import {maxBy} from 'rambda'
12763
12764const compareFn = (x: number) => x % 2 === 0 ? 1 : -1
12765const first = 1
12766const second = 2
12767
12768describe('R.maxBy', () => {
12769 it('happy', () => {
12770 const result = maxBy(compareFn, first, second)
12771 result // $ExpectType 1 | 2
12772 })
12773 it('curried 1', () => {
12774 const result = maxBy(compareFn)(first, second)
12775 result // $ExpectType number
12776 })
12777 it('curried 2', () => {
12778 const result = maxBy<number>(compareFn, first)(second)
12779 result // $ExpectType number
12780 })
12781 it('curried 3', () => {
12782 const result = maxBy(compareFn)(first)(second)
12783 result // $ExpectType number
12784 })
12785})
12786```
12787
12788</details>
12789
12790[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#maxBy)
12791
12792### mean
12793
12794```typescript
12795
12796mean(list: readonly number[]): number
12797```
12798
12799It returns the mean value of `list` input.
12800
12801```javascript
12802R.mean([ 2, 7 ])
12803// => 4.5
12804```
12805
12806<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.mean(%5B%202%2C%207%20%5D)%0A%2F%2F%20%3D%3E%204.5">Try this <strong>R.mean</strong> example in Rambda REPL</a>
12807
12808<details>
12809
12810<summary>All Typescript definitions</summary>
12811
12812```typescript
12813mean(list: readonly number[]): number;
12814```
12815
12816</details>
12817
12818<details>
12819
12820<summary><strong>R.mean</strong> source</summary>
12821
12822```javascript
12823import { sum } from './sum'
12824
12825export function mean(list){
12826 return sum(list) / list.length
12827}
12828```
12829
12830</details>
12831
12832<details>
12833
12834<summary><strong>Tests</strong></summary>
12835
12836```javascript
12837import { mean } from './mean'
12838
12839test('happy', () => {
12840 expect(mean([ 2, 7 ])).toBe(4.5)
12841})
12842
12843test('with NaN', () => {
12844 expect(mean([])).toBeNaN()
12845})
12846```
12847
12848</details>
12849
12850<details>
12851
12852<summary><strong>Typescript</strong> test</summary>
12853
12854```typescript
12855import {mean} from 'rambda'
12856
12857describe('R.mean', () => {
12858 it('happy', () => {
12859 const result = mean([1, 2, 3])
12860
12861 result // $ExpectType number
12862 })
12863})
12864```
12865
12866</details>
12867
12868[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#mean)
12869
12870### median
12871
12872```typescript
12873
12874median(list: readonly number[]): number
12875```
12876
12877It returns the median value of `list` input.
12878
12879```javascript
12880R.median([ 7, 2, 10, 9 ]) // => 8
12881```
12882
12883<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.median(%5B%207%2C%202%2C%2010%2C%209%20%5D)%20%2F%2F%20%3D%3E%208">Try this <strong>R.median</strong> example in Rambda REPL</a>
12884
12885<details>
12886
12887<summary>All Typescript definitions</summary>
12888
12889```typescript
12890median(list: readonly number[]): number;
12891```
12892
12893</details>
12894
12895<details>
12896
12897<summary><strong>R.median</strong> source</summary>
12898
12899```javascript
12900import { mean } from './mean'
12901
12902export function median(list){
12903 const len = list.length
12904 if (len === 0) return NaN
12905 const width = 2 - len % 2
12906 const idx = (len - width) / 2
12907
12908 return mean(Array.prototype.slice
12909 .call(list, 0)
12910 .sort((a, b) => {
12911 if (a === b) return 0
12912
12913 return a < b ? -1 : 1
12914 })
12915 .slice(idx, idx + width))
12916}
12917```
12918
12919</details>
12920
12921<details>
12922
12923<summary><strong>Tests</strong></summary>
12924
12925```javascript
12926import { median } from './median'
12927
12928test('happy', () => {
12929 expect(median([ 2 ])).toEqual(2)
12930 expect(median([ 7, 2, 10, 2, 9 ])).toEqual(7)
12931})
12932
12933test('with empty array', () => {
12934 expect(median([])).toBeNaN()
12935})
12936```
12937
12938</details>
12939
12940<details>
12941
12942<summary><strong>Typescript</strong> test</summary>
12943
12944```typescript
12945import {median} from 'rambda'
12946
12947describe('R.median', () => {
12948 it('happy', () => {
12949 const result = median([1, 2, 3])
12950
12951 result // $ExpectType number
12952 })
12953})
12954```
12955
12956</details>
12957
12958[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#median)
12959
12960### merge
12961
12962```typescript
12963
12964merge<O1 extends object, O2 extends object>(target: O1, newProps: O2): Merge<O2, O1, 'flat'>
12965```
12966
12967It creates a copy of `target` object with overidden `newProps` properties.
12968
12969```javascript
12970const target = { 'foo': 0, 'bar': 1 }
12971const newProps = { 'foo': 7 }
12972
12973const result = R.merge(target, newProps)
12974// => { 'foo': 7, 'bar': 1 }
12975```
12976
12977<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20target%20%3D%20%7B%20'foo'%3A%200%2C%20'bar'%3A%201%20%7D%0Aconst%20newProps%20%3D%20%7B%20'foo'%3A%207%20%7D%0A%0Aconst%20result%20%3D%20R.merge(target%2C%20newProps)%0A%2F%2F%20%3D%3E%20%7B%20'foo'%3A%207%2C%20'bar'%3A%201%20%7D">Try this <strong>R.merge</strong> example in Rambda REPL</a>
12978
12979<details>
12980
12981<summary>All Typescript definitions</summary>
12982
12983```typescript
12984merge<O1 extends object, O2 extends object>(target: O1, newProps: O2): Merge<O2, O1, 'flat'>;
12985merge<O1 extends object>(target: O1): <O2 extends object>(newProps: O2) => Merge<O2, O1, 'flat'>;
12986```
12987
12988</details>
12989
12990<details>
12991
12992<summary><strong>R.merge</strong> source</summary>
12993
12994```javascript
12995export function merge(target, newProps){
12996 if (arguments.length === 1) return _newProps => merge(target, _newProps)
12997
12998 return Object.assign(
12999 {}, target || {}, newProps || {}
13000 )
13001}
13002```
13003
13004</details>
13005
13006<details>
13007
13008<summary><strong>Tests</strong></summary>
13009
13010```javascript
13011import { merge } from './merge'
13012
13013const obj = {
13014 foo : 1,
13015 bar : 2,
13016}
13017
13018test('happy', () => {
13019 expect(merge(obj, { bar : 20 })).toEqual({
13020 foo : 1,
13021 bar : 20,
13022 })
13023})
13024
13025test('curry', () => {
13026 expect(merge(obj)({ baz : 3 })).toEqual({
13027 foo : 1,
13028 bar : 2,
13029 baz : 3,
13030 })
13031})
13032
13033/**
13034 * https://github.com/selfrefactor/rambda/issues/77
13035 */
13036test('when undefined or null instead of object', () => {
13037 expect(merge(null, undefined)).toEqual({})
13038 expect(merge(obj, null)).toEqual(obj)
13039 expect(merge(obj, undefined)).toEqual(obj)
13040 expect(merge(undefined, obj)).toEqual(obj)
13041})
13042```
13043
13044</details>
13045
13046<details>
13047
13048<summary><strong>Typescript</strong> test</summary>
13049
13050```typescript
13051import {merge} from 'rambda'
13052
13053describe('R.merge', () => {
13054 const result = merge({foo: 1}, {bar: 2})
13055 const curriedResult = merge({foo: 1})({bar: 2})
13056
13057 result.foo // $ExpectType number
13058 result.bar // $ExpectType number
13059 curriedResult.bar // $ExpectType number
13060})
13061```
13062
13063</details>
13064
13065[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#merge)
13066
13067### mergeAll
13068
13069```typescript
13070
13071mergeAll<T>(list: object[]): T
13072```
13073
13074It merges all objects of `list` array sequentially and returns the result.
13075
13076```javascript
13077const list = [
13078 {a: 1},
13079 {b: 2},
13080 {c: 3}
13081]
13082const result = R.mergeAll(list)
13083const expected = {
13084 a: 1,
13085 b: 2,
13086 c: 3
13087}
13088// => `result` is equal to `expected`
13089```
13090
13091<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%0A%20%20%7Ba%3A%201%7D%2C%0A%20%20%7Bb%3A%202%7D%2C%0A%20%20%7Bc%3A%203%7D%0A%5D%0Aconst%20result%20%3D%20R.mergeAll(list)%0Aconst%20expected%20%3D%20%7B%0A%20%20a%3A%201%2C%0A%20%20b%3A%202%2C%0A%20%20c%3A%203%0A%7D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.mergeAll</strong> example in Rambda REPL</a>
13092
13093<details>
13094
13095<summary>All Typescript definitions</summary>
13096
13097```typescript
13098mergeAll<T>(list: object[]): T;
13099mergeAll(list: object[]): object;
13100```
13101
13102</details>
13103
13104<details>
13105
13106<summary><strong>R.mergeAll</strong> source</summary>
13107
13108```javascript
13109import { map } from './map'
13110import { merge } from './merge'
13111
13112export function mergeAll(arr){
13113 let willReturn = {}
13114 map(val => {
13115 willReturn = merge(willReturn, val)
13116 }, arr)
13117
13118 return willReturn
13119}
13120```
13121
13122</details>
13123
13124<details>
13125
13126<summary><strong>Tests</strong></summary>
13127
13128```javascript
13129import { mergeAll } from './mergeAll'
13130
13131test('case 1', () => {
13132 const arr = [ { a : 1 }, { b : 2 }, { c : 3 } ]
13133 const expectedResult = {
13134 a : 1,
13135 b : 2,
13136 c : 3,
13137 }
13138 expect(mergeAll(arr)).toEqual(expectedResult)
13139})
13140
13141test('case 2', () => {
13142 expect(mergeAll([ { foo : 1 }, { bar : 2 }, { baz : 3 } ])).toEqual({
13143 foo : 1,
13144 bar : 2,
13145 baz : 3,
13146 })
13147})
13148```
13149
13150</details>
13151
13152<details>
13153
13154<summary><strong>Typescript</strong> test</summary>
13155
13156```typescript
13157import {mergeAll} from 'rambda'
13158
13159describe('R.mergeAll', () => {
13160 it('with passing type', () => {
13161 interface Output {
13162 foo: number,
13163 bar: number,
13164 }
13165 const result = mergeAll<Output>([{foo: 1}, {bar: 2}])
13166 result.foo // $ExpectType number
13167 result.bar // $ExpectType number
13168 })
13169
13170 it('without passing type', () => {
13171 const result = mergeAll([{foo: 1}, {bar: 2}])
13172 result // $ExpectType unknown
13173 })
13174})
13175```
13176
13177</details>
13178
13179[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#mergeAll)
13180
13181### mergeDeepRight
13182
13183```typescript
13184
13185mergeDeepRight<O1 extends object, O2 extends object>(x: O1, y: O2): Merge<O2, O1, 'deep'>
13186```
13187
13188Creates a new object with the own properties of the first object merged with the own properties of the second object. If a key exists in both objects:
13189
13190 - and both values are objects, the two values will be recursively merged
13191 - otherwise the value from the second object will be used.
13192
13193<details>
13194
13195<summary>All Typescript definitions</summary>
13196
13197```typescript
13198mergeDeepRight<O1 extends object, O2 extends object>(x: O1, y: O2): Merge<O2, O1, 'deep'>;
13199mergeDeepRight<O1 extends object>(x: O1): <O2 extends object>(y: O2) => Merge<O2, O1, 'deep'>;
13200```
13201
13202</details>
13203
13204<details>
13205
13206<summary><strong>R.mergeDeepRight</strong> source</summary>
13207
13208```javascript
13209import { type } from './type'
13210
13211export function mergeDeepRight(target, source){
13212 if (arguments.length === 1){
13213 return sourceHolder => mergeDeepRight(target, sourceHolder)
13214 }
13215
13216 const willReturn = JSON.parse(JSON.stringify(target))
13217
13218 Object.keys(source).forEach(key => {
13219 if (type(source[ key ]) === 'Object'){
13220 if (type(target[ key ]) === 'Object'){
13221 willReturn[ key ] = mergeDeepRight(target[ key ], source[ key ])
13222 } else {
13223 willReturn[ key ] = source[ key ]
13224 }
13225 } else {
13226 willReturn[ key ] = source[ key ]
13227 }
13228 })
13229
13230 return willReturn
13231}
13232```
13233
13234</details>
13235
13236<details>
13237
13238<summary><strong>Tests</strong></summary>
13239
13240```javascript
13241// import { mergeDeepRight } from 'ramda'
13242import { mergeDeepRight } from './mergeDeepRight'
13243
13244const slave = {
13245 name : 'evilMe',
13246 age : 10,
13247 contact : {
13248 a : 1,
13249 email : 'foo@example.com',
13250 },
13251}
13252const master = {
13253 age : 40,
13254 contact : { email : 'baz@example.com' },
13255 songs : { title : 'Remains the same' },
13256}
13257
13258test('happy', () => {
13259 const result = mergeDeepRight(slave, master)
13260 const curryResult = mergeDeepRight(slave)(master)
13261 const expected = {
13262 age : 40,
13263 name : 'evilMe',
13264 contact : {
13265 a : 1,
13266 email : 'baz@example.com',
13267 },
13268 songs : { title : 'Remains the same' },
13269 }
13270
13271 expect(result).toEqual(expected)
13272 expect(curryResult).toEqual(expected)
13273})
13274
13275test('ramda compatible test 1', () => {
13276 const a = {
13277 w : 1,
13278 x : 2,
13279 y : { z : 3 },
13280 }
13281 const b = {
13282 a : 4,
13283 b : 5,
13284 c : { d : 6 },
13285 }
13286 const result = mergeDeepRight(a, b)
13287 const expected = {
13288 w : 1,
13289 x : 2,
13290 y : { z : 3 },
13291 a : 4,
13292 b : 5,
13293 c : { d : 6 },
13294 }
13295
13296 expect(result).toEqual(expected)
13297})
13298
13299test('ramda compatible test 2', () => {
13300 const a = {
13301 a : {
13302 b : 1,
13303 c : 2,
13304 },
13305 y : 0,
13306 }
13307 const b = {
13308 a : {
13309 b : 3,
13310 d : 4,
13311 },
13312 z : 0,
13313 }
13314 const result = mergeDeepRight(a, b)
13315 const expected = {
13316 a : {
13317 b : 3,
13318 c : 2,
13319 d : 4,
13320 },
13321 y : 0,
13322 z : 0,
13323 }
13324
13325 expect(result).toEqual(expected)
13326})
13327
13328test('ramda compatible test 3', () => {
13329 const a = {
13330 w : 1,
13331 x : { y : 2 },
13332 }
13333 const result = mergeDeepRight(a, { x : { y : 3 } })
13334 const expected = {
13335 w : 1,
13336 x : { y : 3 },
13337 }
13338 expect(result).toEqual(expected)
13339})
13340```
13341
13342</details>
13343
13344<details>
13345
13346<summary><strong>Typescript</strong> test</summary>
13347
13348```typescript
13349import {mergeDeepRight} from 'rambda'
13350
13351describe('R.mergeDeepRight', () => {
13352 const result = mergeDeepRight({foo: {bar: 1}}, {foo: {bar: 2}})
13353 result.foo.bar // $ExpectType number
13354})
13355```
13356
13357</details>
13358
13359[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#mergeDeepRight)
13360
13361### mergeLeft
13362
13363```typescript
13364
13365mergeLeft<O1 extends object, O2 extends object>(target: O1, newProps: O2): Merge<O2, O1, 'flat'>
13366```
13367
13368Same as `R.merge`, but in opposite direction.
13369
13370```javascript
13371const result = R.mergeLeft(
13372 {a: 10},
13373 {a: 1, b: 2}
13374)
13375// => {a:10, b: 2}
13376```
13377
13378<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.mergeLeft(%0A%20%20%7Ba%3A%2010%7D%2C%0A%20%20%7Ba%3A%201%2C%20b%3A%202%7D%0A)%0A%2F%2F%20%3D%3E%20%7Ba%3A10%2C%20b%3A%202%7D">Try this <strong>R.mergeLeft</strong> example in Rambda REPL</a>
13379
13380<details>
13381
13382<summary>All Typescript definitions</summary>
13383
13384```typescript
13385mergeLeft<O1 extends object, O2 extends object>(target: O1, newProps: O2): Merge<O2, O1, 'flat'>;
13386mergeLeft<O1 extends object>(target: O1): <O2 extends object>(newProps: O2) => Merge<O2, O1, 'flat'>;
13387```
13388
13389</details>
13390
13391<details>
13392
13393<summary><strong>R.mergeLeft</strong> source</summary>
13394
13395```javascript
13396import { merge } from './merge'
13397
13398export function mergeLeft(x, y){
13399 if (arguments.length === 1) return _y => mergeLeft(x, _y)
13400
13401 return merge(y, x)
13402}
13403```
13404
13405</details>
13406
13407<details>
13408
13409<summary><strong>Tests</strong></summary>
13410
13411```javascript
13412import { mergeLeft } from './mergeLeft'
13413
13414const obj = {
13415 foo : 1,
13416 bar : 2,
13417}
13418
13419test('happy', () => {
13420 expect(mergeLeft({ bar : 20 }, obj)).toEqual({
13421 foo : 1,
13422 bar : 20,
13423 })
13424})
13425
13426test('curry', () => {
13427 expect(mergeLeft({ baz : 3 })(obj)).toEqual({
13428 foo : 1,
13429 bar : 2,
13430 baz : 3,
13431 })
13432})
13433
13434test('when undefined or null instead of object', () => {
13435 expect(mergeLeft(null, undefined)).toEqual({})
13436 expect(mergeLeft(obj, null)).toEqual(obj)
13437 expect(mergeLeft(obj, undefined)).toEqual(obj)
13438 expect(mergeLeft(undefined, obj)).toEqual(obj)
13439})
13440```
13441
13442</details>
13443
13444<details>
13445
13446<summary><strong>Typescript</strong> test</summary>
13447
13448```typescript
13449import {mergeLeft} from 'rambda'
13450
13451describe('R.mergeLeft', () => {
13452 const result = mergeLeft({foo: 1}, {bar: 2})
13453 const curriedResult = mergeLeft({foo: 1})({bar: 2})
13454
13455 result.foo // $ExpectType number
13456 result.bar // $ExpectType number
13457 curriedResult.bar // $ExpectType number
13458})
13459```
13460
13461</details>
13462
13463[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#mergeLeft)
13464
13465### min
13466
13467```typescript
13468
13469min<T extends Ord>(x: T, y: T): T
13470```
13471
13472It returns the lesser value between `x` and `y`.
13473
13474```javascript
13475const result = [
13476 R.min(5, 7),
13477 R.min('bar', 'foo'),
13478]
13479// => [5, 'bar']
13480```
13481
13482<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.min(5%2C%207)%2C%20%20%0A%20%20R.min('bar'%2C%20'foo')%2C%20%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B5%2C%20'bar'%5D">Try this <strong>R.min</strong> example in Rambda REPL</a>
13483
13484<details>
13485
13486<summary>All Typescript definitions</summary>
13487
13488```typescript
13489min<T extends Ord>(x: T, y: T): T;
13490min<T extends Ord>(x: T): (y: T) => T;
13491```
13492
13493</details>
13494
13495<details>
13496
13497<summary><strong>R.min</strong> source</summary>
13498
13499```javascript
13500export function min(x, y){
13501 if (arguments.length === 1) return _y => min(x, _y)
13502
13503 return y < x ? y : x
13504}
13505```
13506
13507</details>
13508
13509<details>
13510
13511<summary><strong>Tests</strong></summary>
13512
13513```javascript
13514import { min } from './min'
13515
13516test('happy', () => {
13517 expect(min(2, 1)).toBe(1)
13518 expect(min(1)(2)).toBe(1)
13519})
13520```
13521
13522</details>
13523
13524<details>
13525
13526<summary><strong>Typescript</strong> test</summary>
13527
13528```typescript
13529import {min} from 'rambda'
13530
13531const first = 1
13532const second = 2
13533
13534describe('R.min', () => {
13535 it('happy', () => {
13536 const result = min(first, second)
13537 result // $ExpectType 1 | 2
13538 })
13539 it('curried', () => {
13540 const result = min(first, second)
13541 result // $ExpectType 1 | 2
13542 })
13543 it('curried - cann pass type', () => {
13544 const result = min<number>(first, second)
13545 result // $ExpectType number
13546 })
13547 it('can pass type', () => {
13548 const result = min<number>(first, second)
13549 result // $ExpectType number
13550 })
13551})
13552```
13553
13554</details>
13555
13556[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#min)
13557
13558### minBy
13559
13560```typescript
13561
13562minBy<T>(compareFn: (input: T) => Ord, x: T, y: T): T
13563```
13564
13565It returns the lesser value between `x` and `y` according to `compareFn` function.
13566
13567```javascript
13568const compareFn = Math.abs
13569
13570R.minBy(compareFn, -5, 2) // => -5
13571```
13572
13573<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20compareFn%20%3D%20Math.abs%0A%0AR.minBy(compareFn%2C%20-5%2C%202)%20%2F%2F%20%3D%3E%20-5">Try this <strong>R.minBy</strong> example in Rambda REPL</a>
13574
13575<details>
13576
13577<summary>All Typescript definitions</summary>
13578
13579```typescript
13580minBy<T>(compareFn: (input: T) => Ord, x: T, y: T): T;
13581minBy<T>(compareFn: (input: T) => Ord, x: T): (y: T) => T;
13582minBy<T>(compareFn: (input: T) => Ord): FunctionToolbelt.Curry<(x: T, y: T) => T>;
13583```
13584
13585</details>
13586
13587<details>
13588
13589<summary><strong>R.minBy</strong> source</summary>
13590
13591```javascript
13592import { curry } from './curry'
13593
13594export function minByFn(
13595 compareFn, x, y
13596){
13597 return compareFn(y) < compareFn(x) ? y : x
13598}
13599
13600export const minBy = curry(minByFn)
13601```
13602
13603</details>
13604
13605<details>
13606
13607<summary><strong>Tests</strong></summary>
13608
13609```javascript
13610import { minBy } from './minBy'
13611
13612test('happy', () => {
13613 expect(minBy(
13614 Math.abs, -5, 2
13615 )).toEqual(2)
13616})
13617
13618test('curried', () => {
13619 expect(minBy(Math.abs)(2, -5)).toEqual(2)
13620 expect(minBy(Math.abs)(2)(-5)).toEqual(2)
13621})
13622```
13623
13624</details>
13625
13626<details>
13627
13628<summary><strong>Typescript</strong> test</summary>
13629
13630```typescript
13631import {minBy} from 'rambda'
13632
13633const compareFn = (x: number) => x % 2 === 0 ? 1 : -1
13634const first = 1
13635const second = 2
13636
13637describe('R.minBy', () => {
13638 it('happy', () => {
13639 const result = minBy(compareFn, first, second)
13640 result // $ExpectType 1 | 2
13641 })
13642 it('curried 1', () => {
13643 const result = minBy(compareFn)(first, second)
13644 result // $ExpectType number
13645 })
13646 it('curried 2', () => {
13647 /*
13648 Than should be the case, but passing type is required for some reason
13649 */
13650 const result = minBy<number>(compareFn, first)(second)
13651 result // $ExpectType number
13652 })
13653 it('curried 3', () => {
13654 const result = minBy(compareFn)(first)(second)
13655 result // $ExpectType number
13656 })
13657})
13658```
13659
13660</details>
13661
13662[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#minBy)
13663
13664### modulo
13665
13666```typescript
13667
13668modulo(x: number, y: number): number
13669```
13670
13671Curried version of `x%y`.
13672
13673```javascript
13674R.modulo(17, 3) // => 2
13675```
13676
13677<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.modulo(17%2C%203)%20%2F%2F%20%3D%3E%202">Try this <strong>R.modulo</strong> example in Rambda REPL</a>
13678
13679<details>
13680
13681<summary>All Typescript definitions</summary>
13682
13683```typescript
13684modulo(x: number, y: number): number;
13685modulo(x: number): (y: number) => number;
13686```
13687
13688</details>
13689
13690<details>
13691
13692<summary><strong>R.modulo</strong> source</summary>
13693
13694```javascript
13695export function modulo(x, y){
13696 if (arguments.length === 1) return _y => modulo(x, _y)
13697
13698 return x % y
13699}
13700```
13701
13702</details>
13703
13704<details>
13705
13706<summary><strong>Tests</strong></summary>
13707
13708```javascript
13709import { modulo } from './modulo'
13710
13711test('happy', () => {
13712 expect(modulo(17, 3)).toEqual(2)
13713 expect(modulo(15)(6)).toEqual(3)
13714})
13715```
13716
13717</details>
13718
13719<details>
13720
13721<summary><strong>Typescript</strong> test</summary>
13722
13723```typescript
13724import {modulo} from 'rambda'
13725
13726describe('R.modulo', () => {
13727 it('happy', () => {
13728 const result = modulo(4, 1)
13729
13730 result // $ExpectType number
13731 })
13732 it('curried', () => {
13733 const result = modulo(4)(1)
13734
13735 result // $ExpectType number
13736 })
13737})
13738```
13739
13740</details>
13741
13742[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#modulo)
13743
13744### move
13745
13746```typescript
13747
13748move<T>(fromIndex: number, toIndex: number, list: readonly T[]): T[]
13749```
13750
13751It returns a copy of `list` with exchanged `fromIndex` and `toIndex` elements.
13752
13753> :boom: Rambda.move doesn't support negative indexes - it throws an error.
13754
13755```javascript
13756const list = [1, 2, 3]
13757const result = R.move(0, 1, list)
13758// => [2, 1, 3]
13759```
13760
13761<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20result%20%3D%20R.move(0%2C%201%2C%20list)%0A%2F%2F%20%3D%3E%20%5B2%2C%201%2C%203%5D">Try this <strong>R.move</strong> example in Rambda REPL</a>
13762
13763<details>
13764
13765<summary>All Typescript definitions</summary>
13766
13767```typescript
13768move<T>(fromIndex: number, toIndex: number, list: readonly T[]): T[];
13769move(fromIndex: number, toIndex: number): <T>(list: readonly T[]) => T[];
13770move(fromIndex: number): {
13771 <T>(toIndex: number, list: readonly T[]): T[];
13772 (toIndex: number): <T>(list: readonly T[]) => T[];
13773};
13774```
13775
13776</details>
13777
13778<details>
13779
13780<summary><strong>R.move</strong> source</summary>
13781
13782```javascript
13783import { curry } from './curry'
13784
13785function moveFn(
13786 fromIndex, toIndex, list
13787){
13788 if (fromIndex < 0 || toIndex < 0){
13789 throw new Error('Rambda.move does not support negative indexes')
13790 }
13791 if (fromIndex > list.length - 1 || toIndex > list.length - 1) return list
13792
13793 const clone = list.slice()
13794 clone[ fromIndex ] = list[ toIndex ]
13795 clone[ toIndex ] = list[ fromIndex ]
13796
13797 return clone
13798}
13799
13800export const move = curry(moveFn)
13801```
13802
13803</details>
13804
13805<details>
13806
13807<summary><strong>Tests</strong></summary>
13808
13809```javascript
13810import { move } from './move'
13811const list = [ 1, 2, 3, 4 ]
13812
13813test('happy', () => {
13814 const result = move(
13815 0, 1, list
13816 )
13817
13818 expect(result).toEqual([ 2, 1, 3, 4 ])
13819})
13820
13821test('with negative index', () => {
13822 const errorMessage = 'Rambda.move does not support negative indexes'
13823 expect(() => move(
13824 0, -1, list
13825 )).toThrowWithMessage(Error, errorMessage)
13826 expect(() => move(
13827 -1, 0, list
13828 )).toThrowWithMessage(Error, errorMessage)
13829})
13830
13831test('when indexes are outside the list outbounds', () => {
13832 const result1 = move(
13833 10, 1, list
13834 )
13835 const result2 = move(
13836 1, 10, list
13837 )
13838
13839 expect(result1).toEqual(list)
13840 expect(result2).toEqual(list)
13841})
13842```
13843
13844</details>
13845
13846<details>
13847
13848<summary><strong>Typescript</strong> test</summary>
13849
13850```typescript
13851import {move} from 'rambda'
13852
13853const list = [1, 2, 3]
13854
13855describe('R.move', () => {
13856 it('happy', () => {
13857 const result = move(0, 1, list)
13858
13859 result // $ExpectType number[]
13860 })
13861 it('curried 1', () => {
13862 const result = move(0, 1)(list)
13863
13864 result // $ExpectType number[]
13865 })
13866 it('curried 2', () => {
13867 const result = move(0)(1)(list)
13868
13869 result // $ExpectType number[]
13870 })
13871})
13872```
13873
13874</details>
13875
13876*2 failed Ramda.move specs*
13877
13878> :boom: Reason for the failure: Ramda method does not support negative indexes
13879
13880[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#move)
13881
13882### multiply
13883
13884```typescript
13885
13886multiply(x: number, y: number): number
13887```
13888
13889Curried version of `x*y`.
13890
13891```javascript
13892R.multiply(2, 4) // => 8
13893```
13894
13895<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.multiply(2%2C%204)%20%2F%2F%20%3D%3E%208">Try this <strong>R.multiply</strong> example in Rambda REPL</a>
13896
13897<details>
13898
13899<summary>All Typescript definitions</summary>
13900
13901```typescript
13902multiply(x: number, y: number): number;
13903multiply(x: number): (y: number) => number;
13904```
13905
13906</details>
13907
13908<details>
13909
13910<summary><strong>R.multiply</strong> source</summary>
13911
13912```javascript
13913export function multiply(x, y){
13914 if (arguments.length === 1) return _y => multiply(x, _y)
13915
13916 return x * y
13917}
13918```
13919
13920</details>
13921
13922<details>
13923
13924<summary><strong>Tests</strong></summary>
13925
13926```javascript
13927import { multiply } from './multiply'
13928
13929test('happy', () => {
13930 expect(multiply(2, 4)).toEqual(8)
13931 expect(multiply(2)(4)).toEqual(8)
13932})
13933```
13934
13935</details>
13936
13937<details>
13938
13939<summary><strong>Typescript</strong> test</summary>
13940
13941```typescript
13942import {multiply} from 'rambda'
13943
13944describe('R.multiply', () => {
13945 it('happy', () => {
13946 const result = multiply(4, 1)
13947
13948 result // $ExpectType number
13949 })
13950 it('curried', () => {
13951 const result = multiply(4)(1)
13952
13953 result // $ExpectType number
13954 })
13955})
13956```
13957
13958</details>
13959
13960[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#multiply)
13961
13962### negate
13963
13964```typescript
13965
13966negate(x: number): number
13967```
13968
13969```javascript
13970R.negate(420)// => -420
13971```
13972
13973<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.negate(420)%2F%2F%20%3D%3E%20-420">Try this <strong>R.negate</strong> example in Rambda REPL</a>
13974
13975<details>
13976
13977<summary>All Typescript definitions</summary>
13978
13979```typescript
13980negate(x: number): number;
13981```
13982
13983</details>
13984
13985<details>
13986
13987<summary><strong>R.negate</strong> source</summary>
13988
13989```javascript
13990export function negate(x){
13991 return -x
13992}
13993```
13994
13995</details>
13996
13997<details>
13998
13999<summary><strong>Tests</strong></summary>
14000
14001```javascript
14002import { negate } from './negate'
14003
14004test('negate', () => {
14005 expect(negate(420)).toEqual(-420)
14006 expect(negate(-13)).toEqual(13)
14007})
14008```
14009
14010</details>
14011
14012[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#negate)
14013
14014### none
14015
14016```typescript
14017
14018none<T>(predicate: (x: T) => boolean, list: readonly T[]): boolean
14019```
14020
14021It returns `true`, if all members of array `list` returns `false`, when applied as argument to `predicate` function.
14022
14023```javascript
14024const list = [ 0, 1, 2, 3, 4 ]
14025const predicate = x => x > 6
14026
14027const result = R.none(predicate, arr)
14028// => true
14029```
14030
14031<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%200%2C%201%2C%202%2C%203%2C%204%20%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%206%0A%0Aconst%20result%20%3D%20R.none(predicate%2C%20arr)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.none</strong> example in Rambda REPL</a>
14032
14033<details>
14034
14035<summary>All Typescript definitions</summary>
14036
14037```typescript
14038none<T>(predicate: (x: T) => boolean, list: readonly T[]): boolean;
14039none<T>(predicate: (x: T) => boolean): (list: readonly T[]) => boolean;
14040```
14041
14042</details>
14043
14044<details>
14045
14046<summary><strong>R.none</strong> source</summary>
14047
14048```javascript
14049export function none(predicate, list){
14050 if (arguments.length === 1) return _list => none(predicate, _list)
14051
14052 for (let i = 0; i < list.length; i++){
14053 if (!predicate(list[ i ])) return true
14054 }
14055
14056 return false
14057}
14058```
14059
14060</details>
14061
14062<details>
14063
14064<summary><strong>Tests</strong></summary>
14065
14066```javascript
14067import { none } from './none'
14068
14069const isEven = n => n % 2 === 0
14070const isOdd = n => n % 2 === 1
14071const arr = [ 1, 3, 5, 7, 9, 11 ]
14072
14073test('when true', () => {
14074 expect(none(isEven, arr)).toBeTrue()
14075})
14076
14077test('when false curried', () => {
14078 expect(none(isOdd)(arr)).toBeFalse()
14079})
14080```
14081
14082</details>
14083
14084<details>
14085
14086<summary><strong>Typescript</strong> test</summary>
14087
14088```typescript
14089import {none} from 'rambda'
14090
14091describe('R.none', () => {
14092 it('happy', () => {
14093 const result = none(
14094 x => {
14095 x // $ExpectType number
14096 return x > 0
14097 },
14098 [1, 2, 3]
14099 )
14100 result // $ExpectType boolean
14101 })
14102 it('curried needs a type', () => {
14103 const result = none<number>(x => {
14104 x // $ExpectType number
14105 return x > 0
14106 })([1, 2, 3])
14107 result // $ExpectType boolean
14108 })
14109})
14110```
14111
14112</details>
14113
14114[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#none)
14115
14116### not
14117
14118```typescript
14119
14120not(input: any): boolean
14121```
14122
14123It returns a boolean negated version of `input`.
14124
14125```javascript
14126R.not(false) // true
14127```
14128
14129<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.not(false)%20%2F%2F%20true">Try this <strong>R.not</strong> example in Rambda REPL</a>
14130
14131<details>
14132
14133<summary>All Typescript definitions</summary>
14134
14135```typescript
14136not(input: any): boolean;
14137```
14138
14139</details>
14140
14141<details>
14142
14143<summary><strong>R.not</strong> source</summary>
14144
14145```javascript
14146export function not(input){
14147 return !input
14148}
14149```
14150
14151</details>
14152
14153<details>
14154
14155<summary><strong>Tests</strong></summary>
14156
14157```javascript
14158import { not } from './not'
14159
14160test('not', () => {
14161 expect(not(false)).toEqual(true)
14162 expect(not(true)).toEqual(false)
14163 expect(not(0)).toEqual(true)
14164 expect(not(1)).toEqual(false)
14165})
14166```
14167
14168</details>
14169
14170<details>
14171
14172<summary><strong>Typescript</strong> test</summary>
14173
14174```typescript
14175import {not} from 'rambda'
14176
14177describe('R.not', () => {
14178 it('happy', () => {
14179 const result = not(4)
14180
14181 result // $ExpectType boolean
14182 })
14183})
14184```
14185
14186</details>
14187
14188[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#not)
14189
14190### nth
14191
14192```typescript
14193
14194nth<T>(index: number, list: readonly T[]): T | undefined
14195```
14196
14197Curried version of `list[index]`.
14198
14199```javascript
14200const list = [1, 2, 3]
14201const str = 'foo'
14202
14203const result = [
14204 R.nth(2, list),
14205 R.nth(6, list),
14206 R.nth(0, str),
14207]
14208// => [3, undefined, 'f']
14209```
14210
14211<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20str%20%3D%20'foo'%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.nth(2%2C%20list)%2C%0A%20%20R.nth(6%2C%20list)%2C%0A%20%20R.nth(0%2C%20str)%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B3%2C%20undefined%2C%20'f'%5D">Try this <strong>R.nth</strong> example in Rambda REPL</a>
14212
14213<details>
14214
14215<summary>All Typescript definitions</summary>
14216
14217```typescript
14218nth<T>(index: number, list: readonly T[]): T | undefined;
14219nth(index: number): <T>(list: readonly T[]) => T | undefined;
14220```
14221
14222</details>
14223
14224<details>
14225
14226<summary><strong>R.nth</strong> source</summary>
14227
14228```javascript
14229export function nth(index, list){
14230 if (arguments.length === 1) return _list => nth(index, _list)
14231
14232 const idx = index < 0 ? list.length + index : index
14233
14234 return Object.prototype.toString.call(list) === '[object String]' ?
14235 list.charAt(idx) :
14236 list[ idx ]
14237}
14238```
14239
14240</details>
14241
14242<details>
14243
14244<summary><strong>Tests</strong></summary>
14245
14246```javascript
14247import { nth } from './nth'
14248
14249test('happy', () => {
14250 expect(nth(2, [ 1, 2, 3, 4 ])).toEqual(3)
14251})
14252
14253test('with curry', () => {
14254 expect(nth(2)([ 1, 2, 3, 4 ])).toEqual(3)
14255})
14256
14257test('with string', () => {
14258 expect(nth(2)('foo')).toEqual('o')
14259})
14260
14261test('with negative index', () => {
14262 expect(nth(-3)([ 1, 2, 3, 4 ])).toEqual(2)
14263})
14264```
14265
14266</details>
14267
14268<details>
14269
14270<summary><strong>Typescript</strong> test</summary>
14271
14272```typescript
14273import {nth} from 'rambda'
14274
14275const list = [1, 2, 3]
14276
14277describe('R.nth', () => {
14278 it('happy', () => {
14279 const result = nth(4, list)
14280
14281 result // $ExpectType number | undefined
14282 })
14283 it('curried', () => {
14284 const result = nth(1)(list)
14285
14286 result // $ExpectType number | undefined
14287 })
14288})
14289```
14290
14291</details>
14292
14293[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#nth)
14294
14295### of
14296
14297```typescript
14298
14299of<T>(x: T): T[]
14300```
14301
14302```javascript
14303R.of(null); //=> [null]
14304R.of([42]); //=> [[42]]
14305```
14306
14307<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.of(null)%3B%20%2F%2F%3D%3E%20%5Bnull%5D%0AR.of(%5B42%5D)%3B%20%2F%2F%3D%3E%20%5B%5B42%5D%5D">Try this <strong>R.of</strong> example in Rambda REPL</a>
14308
14309<details>
14310
14311<summary>All Typescript definitions</summary>
14312
14313```typescript
14314of<T>(x: T): T[];
14315```
14316
14317</details>
14318
14319<details>
14320
14321<summary><strong>R.of</strong> source</summary>
14322
14323```javascript
14324export function of(value){
14325 return [ value ]
14326}
14327```
14328
14329</details>
14330
14331<details>
14332
14333<summary><strong>Tests</strong></summary>
14334
14335```javascript
14336import { of } from './of'
14337
14338test('happy', () => {
14339 expect(of(3)).toEqual([ 3 ])
14340
14341 expect(of(null)).toEqual([ null ])
14342})
14343```
14344
14345</details>
14346
14347<details>
14348
14349<summary><strong>Typescript</strong> test</summary>
14350
14351```typescript
14352import {of} from 'ramda'
14353
14354const list = [1, 2, 3]
14355
14356describe('R.of', () => {
14357 it('happy', () => {
14358 const result = of(4)
14359
14360 result // $ExpectType number[]
14361 })
14362 it('curried', () => {
14363 const result = of(list)
14364
14365 result // $ExpectType number[][]
14366 })
14367})
14368```
14369
14370</details>
14371
14372[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#of)
14373
14374### omit
14375
14376```typescript
14377
14378omit<T, K extends string>(propsToOmit: readonly K[], obj: T): Omit<T, K>
14379```
14380
14381It returns a partial copy of an `obj` without `propsToOmit` properties.
14382
14383> :boom: When using this method with `TypeScript`, it is much easier to pass `propsToOmit` as an array. If passing a string, you will need to explicitly declare the output type.
14384
14385```javascript
14386const obj = {a: 1, b: 2, c: 3}
14387const propsToOmit = 'a,c,d'
14388const propsToOmitList = ['a', 'c', 'd']
14389
14390const result = [
14391 R.omit(propsToOmit, obj),
14392 R.omit(propsToOmitList, obj)
14393]
14394// => [{b: 2}, {b: 2}]
14395```
14396
14397<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D%0Aconst%20propsToOmit%20%3D%20'a%2Cc%2Cd'%0Aconst%20propsToOmitList%20%3D%20%5B'a'%2C%20'c'%2C%20'd'%5D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.omit(propsToOmit%2C%20obj)%2C%20%0A%20%20R.omit(propsToOmitList%2C%20obj)%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B%7Bb%3A%202%7D%2C%20%7Bb%3A%202%7D%5D">Try this <strong>R.omit</strong> example in Rambda REPL</a>
14398
14399<details>
14400
14401<summary>All Typescript definitions</summary>
14402
14403```typescript
14404omit<T, K extends string>(propsToOmit: readonly K[], obj: T): Omit<T, K>;
14405omit<K extends string>(propsToOmit: readonly K[]): <T>(obj: T) => Omit<T, K>;
14406omit<T, U>(propsToOmit: string, obj: T): U;
14407omit<T, U>(propsToOmit: string): (obj: T) => U;
14408omit<T>(propsToOmit: string, obj: object): T;
14409omit<T>(propsToOmit: string): (obj: object) => T;
14410```
14411
14412</details>
14413
14414<details>
14415
14416<summary><strong>R.omit</strong> source</summary>
14417
14418```javascript
14419export function omit(propsToOmit, obj){
14420 if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)
14421
14422 if (obj === null || obj === undefined){
14423 return undefined
14424 }
14425
14426 const propsToOmitValue =
14427 typeof propsToOmit === 'string' ? propsToOmit.split(',') : propsToOmit
14428
14429 const willReturn = {}
14430
14431 for (const key in obj){
14432 if (!propsToOmitValue.includes(key)){
14433 willReturn[ key ] = obj[ key ]
14434 }
14435 }
14436
14437 return willReturn
14438}
14439```
14440
14441</details>
14442
14443<details>
14444
14445<summary><strong>Tests</strong></summary>
14446
14447```javascript
14448import { omit } from './omit'
14449
14450test('with string as condition', () => {
14451 const obj = {
14452 a : 1,
14453 b : 2,
14454 c : 3,
14455 }
14456 const result = omit('a,c', obj)
14457 const resultCurry = omit('a,c')(obj)
14458 const expectedResult = { b : 2 }
14459
14460 expect(result).toEqual(expectedResult)
14461 expect(resultCurry).toEqual(expectedResult)
14462})
14463
14464test('with null', () => {
14465 expect(omit('a,b', null)).toEqual(undefined)
14466})
14467
14468test('doesn\'t work with number as property', () => {
14469 expect(omit([ 42 ], {
14470 a : 1,
14471 42 : 2,
14472 })).toEqual({
14473 42 : 2,
14474 a : 1,
14475 })
14476})
14477
14478test('happy', () => {
14479 expect(omit([ 'a', 'c' ])({
14480 a : 'foo',
14481 b : 'bar',
14482 c : 'baz',
14483 })).toEqual({ b : 'bar' })
14484})
14485```
14486
14487</details>
14488
14489<details>
14490
14491<summary><strong>Typescript</strong> test</summary>
14492
14493```typescript
14494import {omit} from 'rambda'
14495
14496describe('R.omit with array as props input', () => {
14497 it('allow Typescript to infer object type', () => {
14498 const input = {a: 'foo', b: 2, c: 3, d: 4}
14499 const result = omit(['b,c'], input)
14500
14501 result.a // $ExpectType string
14502 result.d // $ExpectType number
14503
14504 const curriedResult = omit(['a,c'], input)
14505
14506 curriedResult.a // $ExpectType string
14507 curriedResult.d // $ExpectType number
14508 })
14509
14510 it('declare type of input object', () => {
14511 interface Input {
14512 a: string,
14513 b: number,
14514 c: number,
14515 d: number,
14516 }
14517 const input: Input = {a: 'foo', b: 2, c: 3, d: 4}
14518 const result = omit(['b,c'], input)
14519 result // $ExpectType Pick<Input, "b" | "a" | "c" | "d">
14520
14521 result.a // $ExpectType string
14522 result.d // $ExpectType number
14523
14524 const curriedResult = omit(['a,c'], input)
14525
14526 curriedResult.a // $ExpectType string
14527 curriedResult.d // $ExpectType number
14528 })
14529})
14530
14531describe('R.omit with string as props input', () => {
14532 interface Output {
14533 b: number,
14534 d: number,
14535 }
14536
14537 it('explicitly declare output', () => {
14538 const result = omit<Output>('a,c', {a: 1, b: 2, c: 3, d: 4})
14539 result // $ExpectType Output
14540 result.b // $ExpectType number
14541
14542 const curriedResult = omit<Output>('a,c')({a: 1, b: 2, c: 3, d: 4})
14543
14544 curriedResult.b // $ExpectType number
14545 })
14546
14547 it('explicitly declare input and output', () => {
14548 interface Input {
14549 a: number,
14550 b: number,
14551 c: number,
14552 d: number,
14553 }
14554 const result = omit<Input, Output>('a,c', {a: 1, b: 2, c: 3, d: 4})
14555 result // $ExpectType Output
14556 result.b // $ExpectType number
14557
14558 const curriedResult = omit<Input, Output>('a,c')({
14559 a: 1,
14560 b: 2,
14561 c: 3,
14562 d: 4,
14563 })
14564
14565 curriedResult.b // $ExpectType number
14566 })
14567
14568 it('without passing type', () => {
14569 const result = omit('a,c', {a: 1, b: 2, c: 3, d: 4})
14570 result // $ExpectType unknown
14571 })
14572})
14573```
14574
14575</details>
14576
14577[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#omit)
14578
14579### once
14580
14581```typescript
14582
14583once<T extends (...args: any[]) => any>(func: T): T
14584```
14585
14586It returns a function, which invokes only once `fn` function.
14587
14588```javascript
14589let result = 0
14590const addOnce = R.once((x) => result = result + x)
14591
14592addOnce(1)
14593addOnce(1)
14594// => 1
14595```
14596
14597<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20let%20result%20%3D%200%0Aconst%20addOnce%20%3D%20R.once((x)%20%3D%3E%20result%20%3D%20result%20%2B%20x)%0A%0AaddOnce(1)%0AaddOnce(1)%0A%2F%2F%20%3D%3E%201">Try this <strong>R.once</strong> example in Rambda REPL</a>
14598
14599<details>
14600
14601<summary>All Typescript definitions</summary>
14602
14603```typescript
14604once<T extends (...args: any[]) => any>(func: T): T;
14605```
14606
14607</details>
14608
14609<details>
14610
14611<summary><strong>R.once</strong> source</summary>
14612
14613```javascript
14614import { curry } from './curry'
14615
14616function onceFn(fn, context){
14617 let result
14618
14619 return function (){
14620 if (fn){
14621 result = fn.apply(context || this, arguments)
14622 fn = null
14623 }
14624
14625 return result
14626 }
14627}
14628
14629export function once(fn, context){
14630 if (arguments.length === 1){
14631 const wrap = onceFn(fn, context)
14632
14633 return curry(wrap)
14634 }
14635
14636 return onceFn(fn, context)
14637}
14638```
14639
14640</details>
14641
14642<details>
14643
14644<summary><strong>Tests</strong></summary>
14645
14646```javascript
14647import { once } from './once'
14648
14649test('with counter', () => {
14650 let counter = 0
14651 const runOnce = once(x => {
14652 counter++
14653
14654 return x + 2
14655 })
14656 expect(runOnce(1)).toEqual(3)
14657 runOnce(1)
14658 runOnce(1)
14659 runOnce(1)
14660 expect(counter).toEqual(1)
14661})
14662
14663test('happy path', () => {
14664 const addOneOnce = once((
14665 a, b, c
14666 ) => a + b + c, 1)
14667
14668 expect(addOneOnce(
14669 10, 20, 30
14670 )).toBe(60)
14671 expect(addOneOnce(40)).toEqual(60)
14672})
14673```
14674
14675</details>
14676
14677<details>
14678
14679<summary><strong>Typescript</strong> test</summary>
14680
14681```typescript
14682import {once} from 'rambda'
14683
14684describe('R.once', () => {
14685 it('happy', () => {
14686 const runOnce = once((x: number) => {
14687 return x + 2
14688 })
14689
14690 const result = runOnce(1)
14691 result // $ExpectType number
14692 })
14693})
14694```
14695
14696</details>
14697
14698*1 failed Ramda.once specs*
14699
14700> :boom: Reason for the failure: Ramda method retains arity
14701
14702[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#once)
14703
14704### or
14705
14706```typescript
14707
14708or<T, U>(a: T, b: U): T | U
14709```
14710
14711Logical OR
14712
14713```javascript
14714R.or(false, true); // => true
14715R.or(false, false); // => false
14716R.or(false, 'foo'); // => 'foo'
14717```
14718
14719<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.or(false%2C%20true)%3B%20%2F%2F%20%3D%3E%20true%0AR.or(false%2C%20false)%3B%20%2F%2F%20%3D%3E%20false%0AR.or(false%2C%20'foo')%3B%20%2F%2F%20%3D%3E%20'foo'">Try this <strong>R.or</strong> example in Rambda REPL</a>
14720
14721<details>
14722
14723<summary>All Typescript definitions</summary>
14724
14725```typescript
14726or<T, U>(a: T, b: U): T | U;
14727or<T>(a: T): <U>(b: U) => T | U;
14728```
14729
14730</details>
14731
14732<details>
14733
14734<summary><strong>R.or</strong> source</summary>
14735
14736```javascript
14737export function or(a, b){
14738 if (arguments.length === 1) return _b => or(a, _b)
14739
14740 return a || b
14741}
14742```
14743
14744</details>
14745
14746<details>
14747
14748<summary><strong>Tests</strong></summary>
14749
14750```javascript
14751import { or } from './or'
14752
14753test('happy', () => {
14754 expect(or(0, 'foo')).toBe('foo')
14755 expect(or(true, true)).toBeTrue()
14756 expect(or(false)(true)).toBeTrue()
14757 expect(or(false, false)).toBeFalse()
14758})
14759```
14760
14761</details>
14762
14763<details>
14764
14765<summary><strong>Typescript</strong> test</summary>
14766
14767```typescript
14768import {or} from 'ramda'
14769
14770describe('R.or', () => {
14771 it('happy', () => {
14772 const result = or(true, false)
14773 result // $ExpectType boolean
14774 })
14775 it('curried', () => {
14776 const result = or(1)('foo')
14777 result // $ExpectType number | "foo"
14778 })
14779})
14780```
14781
14782</details>
14783
14784[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#or)
14785
14786### over
14787
14788```typescript
14789
14790over<T>(lens: Lens, fn: Arity1Fn, value: T): T
14791```
14792
14793It returns a copied **Object** or **Array** with modified value received by applying function `fn` to `lens` focus.
14794
14795```javascript
14796const headLens = R.lensIndex(0)
14797
14798R.over(headLens, R.toUpper, ['foo', 'bar', 'baz']) //=> ['FOO', 'bar', 'baz']
14799```
14800
14801<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20headLens%20%3D%20R.lensIndex(0)%0A%20%0AR.over(headLens%2C%20R.toUpper%2C%20%5B'foo'%2C%20'bar'%2C%20'baz'%5D)%20%2F%2F%3D%3E%20%5B'FOO'%2C%20'bar'%2C%20'baz'%5D">Try this <strong>R.over</strong> example in Rambda REPL</a>
14802
14803<details>
14804
14805<summary>All Typescript definitions</summary>
14806
14807```typescript
14808over<T>(lens: Lens, fn: Arity1Fn, value: T): T;
14809over<T>(lens: Lens, fn: Arity1Fn, value: readonly T[]): T[];
14810over(lens: Lens, fn: Arity1Fn): <T>(value: T) => T;
14811over(lens: Lens, fn: Arity1Fn): <T>(value: readonly T[]) => T[];
14812over(lens: Lens): <T>(fn: Arity1Fn, value: T) => T;
14813over(lens: Lens): <T>(fn: Arity1Fn, value: readonly T[]) => T[];
14814```
14815
14816</details>
14817
14818<details>
14819
14820<summary><strong>R.over</strong> source</summary>
14821
14822```javascript
14823import { curry } from './curry'
14824
14825const Identity = x => ({
14826 x,
14827 map : fn => Identity(fn(x)),
14828})
14829
14830function overFn(
14831 lens, fn, object
14832){
14833 return lens(x => Identity(fn(x)))(object).x
14834}
14835
14836export const over = curry(overFn)
14837```
14838
14839</details>
14840
14841<details>
14842
14843<summary><strong>Tests</strong></summary>
14844
14845```javascript
14846import { assoc } from './assoc'
14847import { lens } from './lens'
14848import { lensIndex } from './lensIndex'
14849import { lensPath } from './lensPath'
14850import { over } from './over'
14851import { prop } from './prop'
14852import { toUpper } from './toUpper'
14853
14854const testObject = {
14855 foo : 'bar',
14856 baz : {
14857 a : 'x',
14858 b : 'y',
14859 },
14860}
14861
14862test('assoc lens', () => {
14863 const assocLens = lens(prop('foo'), assoc('foo'))
14864 const result = over(
14865 assocLens, toUpper, testObject
14866 )
14867 const expected = {
14868 ...testObject,
14869 foo : 'BAR',
14870 }
14871 expect(result).toEqual(expected)
14872 })
14873
14874 test('path lens', () => {
14875 const pathLens = lensPath('baz.a')
14876 const result = over(
14877 pathLens, toUpper, testObject
14878 )
14879 const expected = {
14880 ...testObject,
14881 baz : {
14882 a : 'X',
14883 b : 'y',
14884 },
14885 }
14886 expect(result).toEqual(expected)
14887})
14888
14889test('index lens', () => {
14890 const indexLens = lensIndex(0)
14891 const result = over(indexLens, toUpper)(['foo', 'bar'])
14892 expect(result).toEqual([ 'FOO', 'bar' ])
14893})
14894```
14895
14896</details>
14897
14898[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#over)
14899
14900### partial
14901
14902```typescript
14903
14904partial<V0, V1, T>(fn: (x0: V0, x1: V1) => T, args: [V0]): (x1: V1) => T
14905```
14906
14907It is very similar to `R.curry`, but you can pass initial arguments when you create the curried function.
14908
14909`R.partial` will keep returning a function until all the arguments that the function `fn` expects are passed.
14910The name comes from the fact that you partially inject the inputs.
14911
14912> :boom: Rambda's partial doesn't need the input arguments to be wrapped as array.
14913
14914```javascript
14915const fn = (title, firstName, lastName) => {
14916 return title + ' ' + firstName + ' ' + lastName + '!'
14917}
14918
14919const canPassAnyNumberOfArguments = R.partial(fn, 'Hello')
14920const ramdaStyle = R.partial(fn, ['Hello'])
14921
14922const finalFn = canPassAnyNumberOfArguments('Foo')
14923
14924finalFn('Bar') // => 'Hello, Foo Bar!'
14925```
14926
14927<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20fn%20%3D%20(title%2C%20firstName%2C%20lastName)%20%3D%3E%20%7B%0A%20%20return%20title%20%2B%20'%20'%20%2B%20firstName%20%2B%20'%20'%20%2B%20lastName%20%2B%20'!'%0A%7D%0A%0Aconst%20canPassAnyNumberOfArguments%20%3D%20R.partial(fn%2C%20'Hello')%0Aconst%20ramdaStyle%20%3D%20R.partial(fn%2C%20%5B'Hello'%5D)%0A%0Aconst%20finalFn%20%3D%20canPassAnyNumberOfArguments('Foo')%0A%0AfinalFn('Bar')%20%2F%2F%20%3D%3E%20%20'Hello%2C%20Foo%20Bar!'">Try this <strong>R.partial</strong> example in Rambda REPL</a>
14928
14929<details>
14930
14931<summary>All Typescript definitions</summary>
14932
14933```typescript
14934partial<V0, V1, T>(fn: (x0: V0, x1: V1) => T, args: [V0]): (x1: V1) => T;
14935partial<V0, V1, V2, T>(fn: (x0: V0, x1: V1, x2: V2) => T, args: [V0, V1]): (x2: V2) => T;
14936partial<V0, V1, V2, T>(fn: (x0: V0, x1: V1, x2: V2) => T, args: [V0]): (x1: V1, x2: V2) => T;
14937partial<V0, V1, V2, V3, T>(fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T, args: [V0, V1, V2]): (x2: V3) => T;
14938partial<V0, V1, V2, V3, T>(fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T, args: [V0, V1]): (x2: V2, x3: V3) => T;
14939partial<V0, V1, V2, V3, T>(fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T, args: [V0]): (x1: V1, x2: V2, x3: V3) => T;
14940partial<T>(fn: (...a: any[]) => T, args: any[]): (...x: any[]) => T;
14941```
14942
14943</details>
14944
14945<details>
14946
14947<summary><strong>R.partial</strong> source</summary>
14948
14949```javascript
14950export function partial(fn, ...args){
14951 const len = fn.length
14952
14953 return (...rest) => {
14954 if (args.length + rest.length >= len){
14955 return fn(...args, ...rest)
14956 }
14957
14958 return partial(fn, ...[ ...args, ...rest ])
14959 }
14960}
14961```
14962
14963</details>
14964
14965<details>
14966
14967<summary><strong>Tests</strong></summary>
14968
14969```javascript
14970import { partial } from './partial'
14971import { type } from './type'
14972
14973const greet = (
14974 salutation, title, firstName, lastName
14975) =>
14976 salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'
14977
14978test('happy', () => {
14979 const canPassAnyNumberOfArguments = partial(
14980 greet, 'Hello', 'Ms.'
14981 )
14982 const fn = canPassAnyNumberOfArguments('foo')
14983 const sayHello = partial(greet, [ 'Hello' ])
14984 const sayHelloRamda = partial(sayHello, [ 'Ms.' ])
14985
14986 expect(type(fn)).toBe('Function')
14987
14988 expect(fn('bar')).toBe('Hello, Ms. foo bar!')
14989 expect(sayHelloRamda('foo', 'bar')).toBe('Hello, Ms. foo bar!')
14990})
14991
14992test('extra arguments are ignored', () => {
14993 const canPassAnyNumberOfArguments = partial(
14994 greet, 'Hello', 'Ms.'
14995 )
14996 const fn = canPassAnyNumberOfArguments('foo')
14997
14998 expect(type(fn)).toBe('Function')
14999
15000 expect(fn(
15001 'bar', 1, 2
15002 )).toBe('Hello, Ms. foo bar!')
15003})
15004
15005test('when array is input', () => {
15006 const fooFn = (
15007 a, b, c, d
15008 ) => ({
15009 a,
15010 b,
15011 c,
15012 d,
15013 })
15014 const barFn = partial(
15015 fooFn, [ 1, 2 ], []
15016 )
15017
15018 expect(barFn(1, 2)).toEqual({
15019 a : [ 1, 2 ],
15020 b : [],
15021 c : 1,
15022 d : 2,
15023 })
15024})
15025
15026test('ramda spec', () => {
15027 const sayHello = partial(greet, 'Hello')
15028 const sayHelloToMs = partial(sayHello, 'Ms.')
15029
15030 expect(sayHelloToMs('Jane', 'Jones')).toBe('Hello, Ms. Jane Jones!')
15031})
15032```
15033
15034</details>
15035
15036<details>
15037
15038<summary><strong>Typescript</strong> test</summary>
15039
15040```typescript
15041import {partial} from 'rambda'
15042
15043describe('R.partial', () => {
15044 it('happy', () => {
15045 function greet(
15046 salutation: string,
15047 title: string,
15048 firstName: string,
15049 lastName: string
15050 ) {
15051 return `${salutation}, ${title} ${firstName} ${lastName}!`
15052 }
15053
15054 const sayHello = partial(greet, ['Hello'])
15055 const sayHelloToMs = partial(sayHello, ['Ms.'])
15056 const result = sayHelloToMs('Jane', 'Jones')
15057 result // $ExpectType string
15058 })
15059})
15060```
15061
15062</details>
15063
15064[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#partial)
15065
15066### partition
15067
15068```typescript
15069
15070partition<T>(
15071 predicate: Predicate<T>,
15072 input: readonly T[]
15073): [T[], T[]]
15074```
15075
15076It will return array of two objects/arrays according to `predicate` function. The first member holds all instanses of `input` that pass the `predicate` function, while the second member - those who doesn't.
15077
15078```javascript
15079const list = [1, 2, 3]
15080const obj = {a: 1, b: 2, c: 3}
15081const predicate = x => x > 2
15082
15083const result = [
15084 R.partition(predicate, list),
15085 R.partition(predicate, obj)
15086]
15087const expected = [
15088 [[3], [1, 2]],
15089 [{c: 3}, {a: 1, b: 2}],
15090]
15091// `result` is equal to `expected`
15092```
15093
15094<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20obj%20%3D%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%202%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.partition(predicate%2C%20list)%2C%0A%20%20R.partition(predicate%2C%20obj)%0A%5D%0Aconst%20expected%20%3D%20%5B%0A%20%20%5B%5B3%5D%2C%20%5B1%2C%202%5D%5D%2C%0A%20%20%5B%7Bc%3A%203%7D%2C%20%20%7Ba%3A%201%2C%20b%3A%202%7D%5D%2C%0A%5D%0A%2F%2F%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.partition</strong> example in Rambda REPL</a>
15095
15096<details>
15097
15098<summary>All Typescript definitions</summary>
15099
15100```typescript
15101partition<T>(
15102 predicate: Predicate<T>,
15103 input: readonly T[]
15104): [T[], T[]];
15105partition<T>(
15106 predicate: Predicate<T>
15107): (input: readonly T[]) => [T[], T[]];
15108partition<T>(
15109 predicate: (x: T, prop?: string) => boolean,
15110 input: { [key: string]: T}
15111): [{ [key: string]: T}, { [key: string]: T}];
15112partition<T>(
15113 predicate: (x: T, prop?: string) => boolean
15114): (input: { [key: string]: T}) => [{ [key: string]: T}, { [key: string]: T}];
15115```
15116
15117</details>
15118
15119<details>
15120
15121<summary><strong>R.partition</strong> source</summary>
15122
15123```javascript
15124import { _isArray } from './_internals/_isArray'
15125
15126export function partitionObject(predicate, iterable){
15127 const yes = {}
15128 const no = {}
15129 Object.entries(iterable).forEach(([ prop, value ]) => {
15130 if (predicate(value, prop)){
15131 yes[ prop ] = value
15132 } else {
15133 no[ prop ] = value
15134 }
15135 })
15136
15137 return [ yes, no ]
15138}
15139
15140export function partitionArray(predicate, list){
15141 const yes = []
15142 const no = []
15143 let counter = -1
15144
15145 while (counter++ < list.length - 1){
15146 if (predicate(list[ counter ])){
15147 yes.push(list[ counter ])
15148 } else {
15149 no.push(list[ counter ])
15150 }
15151 }
15152
15153 return [ yes, no ]
15154}
15155
15156export function partition(predicate, iterable){
15157 if (arguments.length === 1){
15158 return listHolder => partition(predicate, listHolder)
15159 }
15160 if (!_isArray(iterable)) return partitionObject(predicate, iterable)
15161
15162 return partitionArray(predicate, iterable)
15163}
15164```
15165
15166</details>
15167
15168<details>
15169
15170<summary><strong>Tests</strong></summary>
15171
15172```javascript
15173import { partition } from './partition'
15174
15175test('with array', () => {
15176 const predicate = (x) => {
15177
15178 return x > 2
15179 }
15180 const list = [ 1, 2, 3, 4 ]
15181
15182 const result = partition(predicate, list)
15183 const expectedResult = [
15184 [ 3, 4 ],
15185 [ 1, 2 ],
15186 ]
15187
15188 expect(result).toEqual(expectedResult)
15189})
15190
15191test('with object', () => {
15192 const predicate = (value, prop) => {
15193 expect(typeof prop).toBe('string')
15194
15195 return value > 2
15196 }
15197 const hash = {
15198 a : 1,
15199 b : 2,
15200 c : 3,
15201 d : 4,
15202 }
15203
15204 const result = partition(predicate)(hash)
15205 const expectedResult = [
15206 {
15207 c : 3,
15208 d : 4,
15209 },
15210 {
15211 a : 1,
15212 b : 2,
15213 },
15214 ]
15215
15216 expect(result).toEqual(expectedResult)
15217})
15218
15219test('readme example', () => {
15220 const list = [ 1, 2, 3 ]
15221 const obj = {
15222 a : 1,
15223 b : 2,
15224 c : 3,
15225 }
15226 const predicate = x => x > 2
15227
15228 const result = [ partition(predicate, list), partition(predicate, obj) ]
15229 const expected = [
15230 [ [ 3 ], [ 1, 2 ] ],
15231 [
15232 { c : 3 },
15233 {
15234 a : 1,
15235 b : 2,
15236 },
15237 ],
15238 ]
15239 expect(result).toEqual(expected)
15240})
15241```
15242
15243</details>
15244
15245<details>
15246
15247<summary><strong>Typescript</strong> test</summary>
15248
15249```typescript
15250import {partition} from 'rambda'
15251
15252describe('R.partition', () => {
15253 it('with array', () => {
15254 const predicate = (x: number) => {
15255 return x > 2
15256 }
15257 const list = [1, 2, 3, 4]
15258
15259 const result = partition(predicate, list)
15260 const curriedResult = partition(predicate)(list)
15261 result // $ExpectType [number[], number[]]
15262 curriedResult // $ExpectType [number[], number[]]
15263 })
15264
15265 it('with object', () => {
15266 const predicate = (value: number, prop?: string) => {
15267 return value > 2
15268 }
15269 const hash = {
15270 a: 1,
15271 b: 2,
15272 c: 3,
15273 d: 4,
15274 }
15275
15276 const result = partition(predicate, hash)
15277 const curriedResult = partition(predicate)(hash)
15278 result[0] // $ExpectType { [key: string]: number; }
15279 result[1] // $ExpectType { [key: string]: number; }
15280 curriedResult[0] // $ExpectType { [key: string]: number; }
15281 curriedResult[1] // $ExpectType { [key: string]: number; }
15282 })
15283})
15284```
15285
15286</details>
15287
15288*1 failed Ramda.partition specs*
15289
15290> :boom: Reason for the failure: Ramda library supports fantasy-land
15291
15292[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#partition)
15293
15294### path
15295
15296```typescript
15297
15298path<Input, T>(pathToSearch: Path, obj: Input): T | undefined
15299```
15300
15301If `pathToSearch` is `'a.b'` then it will return `1` if `obj` is `{a:{b:1}}`.
15302
15303It will return `undefined`, if such path is not found.
15304
15305> :boom: String anotation of `pathToSearch` is one of the differences between `Rambda` and `Ramda`.
15306
15307```javascript
15308const obj = {a: {b: 1}}
15309const pathToSearch = 'a.b'
15310const pathToSearchList = ['a', 'b']
15311
15312const result = [
15313 R.path(pathToSearch, obj),
15314 R.path(pathToSearchList, obj),
15315 R.path('a.b.c.d', obj)
15316]
15317// => [1, 1, undefined]
15318```
15319
15320<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7Ba%3A%20%7Bb%3A%201%7D%7D%0Aconst%20pathToSearch%20%3D%20'a.b'%0Aconst%20pathToSearchList%20%3D%20%5B'a'%2C%20'b'%5D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.path(pathToSearch%2C%20obj)%2C%0A%20%20R.path(pathToSearchList%2C%20obj)%2C%0A%20%20R.path('a.b.c.d'%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5B1%2C%201%2C%20undefined%5D">Try this <strong>R.path</strong> example in Rambda REPL</a>
15321
15322<details>
15323
15324<summary>All Typescript definitions</summary>
15325
15326```typescript
15327path<Input, T>(pathToSearch: Path, obj: Input): T | undefined;
15328path<T>(pathToSearch: Path, obj: any): T | undefined;
15329path<T>(pathToSearch: Path): (obj: any) => T | undefined;
15330path<Input, T>(pathToSearch: Path): (obj: Input) => T | undefined;
15331```
15332
15333</details>
15334
15335<details>
15336
15337<summary><strong>R.path</strong> source</summary>
15338
15339```javascript
15340export function path(pathInput, obj){
15341 if (arguments.length === 1) return _obj => path(pathInput, _obj)
15342
15343 if (obj === null || obj === undefined){
15344 return undefined
15345 }
15346 let willReturn = obj
15347 let counter = 0
15348
15349 const pathArrValue =
15350 typeof pathInput === 'string' ? pathInput.split('.') : pathInput
15351
15352 while (counter < pathArrValue.length){
15353 if (willReturn === null || willReturn === undefined){
15354 return undefined
15355 }
15356 willReturn = willReturn[ pathArrValue[ counter ] ]
15357 counter++
15358 }
15359
15360 return willReturn
15361}
15362```
15363
15364</details>
15365
15366<details>
15367
15368<summary><strong>Tests</strong></summary>
15369
15370```javascript
15371import { path } from './path'
15372
15373test('with array inside object', () => {
15374 const obj = { a : { b : [ 1, { c : 1 } ] } }
15375
15376 expect(path('a.b.1.c', obj)).toBe(1)
15377})
15378
15379test('works with undefined', () => {
15380 const obj = { a : { b : { c : 1 } } }
15381
15382 expect(path('a.b.c.d.f', obj)).toBeUndefined()
15383 expect(path('foo.babaz', undefined)).toBeUndefined()
15384 expect(path('foo.babaz')(undefined)).toBeUndefined()
15385})
15386
15387test('works with string instead of array', () => {
15388 expect(path('foo.bar.baz')({ foo : { bar : { baz : 'yes' } } })).toEqual('yes')
15389})
15390
15391test('path', () => {
15392 expect(path([ 'foo', 'bar', 'baz' ])({ foo : { bar : { baz : 'yes' } } })).toEqual('yes')
15393
15394 expect(path([ 'foo', 'bar', 'baz' ])(null)).toBeUndefined()
15395
15396 expect(path([ 'foo', 'bar', 'baz' ])({ foo : { bar : 'baz' } })).toBeUndefined()
15397})
15398```
15399
15400</details>
15401
15402<details>
15403
15404<summary><strong>Typescript</strong> test</summary>
15405
15406```typescript
15407import {path} from 'rambda'
15408
15409interface Input {
15410 a: number,
15411 b: {
15412 c: boolean,
15413 },
15414}
15415
15416describe('R.path', () => {
15417 it('without specified input type', () => {
15418 const input = {a: 1, b: {c: true}}
15419 const result = path<boolean>('a.b.c', input)
15420 const resultCurried = path<boolean>('a.b.c')(input)
15421 result // $ExpectType boolean | undefined
15422 resultCurried // $ExpectType boolean | undefined
15423 })
15424
15425 it('without specified output type', () => {
15426 const input = {a: 1, b: {c: true}}
15427 const result = path('a.b.c', input)
15428 result // $ExpectType unknown
15429 })
15430
15431 it('with string as path', () => {
15432 const input: Input = {a: 1, b: {c: true}}
15433 const resultA = path<boolean>('a.b.c', input)
15434 const resultB = path<boolean>('a.b.c')(input)
15435 resultA // $ExpectType boolean | undefined
15436 resultB // $ExpectType boolean | undefined
15437 })
15438 it('with array as path', () => {
15439 const input: Input = {a: 1, b: {c: true}}
15440 const resultA = path<boolean>(['a', 'b', 'c'], input)
15441 const resultB = path<boolean>(['a', 'b', 'c'])(input)
15442 resultA // $ExpectType boolean | undefined
15443 resultB // $ExpectType boolean | undefined
15444 })
15445})
15446
15447describe('path with specified input', () => {
15448 it('with string as path', () => {
15449 const input: Input = {a: 1, b: {c: true}}
15450 // const wrongInput = { a: 1, b: true }
15451 // const resultA = path<Input, boolean>('a.b.c', wrongInput)
15452 const resultA = path<Input, boolean>('a.b.c', input)
15453 const resultB = path<Input, boolean>('a.b.c')(input)
15454 resultA // $ExpectType boolean | undefined
15455 resultB // $ExpectType boolean | undefined
15456 })
15457 it('with array as path', () => {
15458 const input: Input = {a: 1, b: {c: true}}
15459 const resultA = path<Input, boolean>(['a', 'b', 'c'], input)
15460 const resultB = path<Input, boolean>(['a', 'b', 'c'])(input)
15461 resultA // $ExpectType boolean | undefined
15462 resultB // $ExpectType boolean | undefined
15463 })
15464})
15465```
15466
15467</details>
15468
15469<details>
15470
15471<summary>1 failed <italic>Ramda.path</italic> specs
15472
15473> :boom: Reason for the failure: Ramda method supports negative indexes
15474</summary>
15475
15476```javascript
15477var R = require('../../../../dist/rambda.js');
15478var eq = require('./shared/eq');
15479
15480describe('path', function() {
15481 var deepObject = {a: {b: {c: 'c'}}, falseVal: false, nullVal: null, undefinedVal: undefined, arrayVal: ['arr']};
15482 it('takes a path that contains negative indices into arrays', function() {
15483 eq(R.path(['x', -2], {x: ['a', 'b', 'c', 'd']}), 'c');
15484 eq(R.path([-1, 'y'], [{x: 1, y: 99}, {x: 2, y: 98}, {x: 3, y: 97}]), 97);
15485 });
15486});
15487```
15488
15489</details>
15490
15491[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#path)
15492
15493### pathEq
15494
15495```typescript
15496
15497pathEq(pathToSearch: Path, target: any, input: any): boolean
15498```
15499
15500It returns `true` if `pathToSearch` of `input` object is equal to `target` value.
15501
15502`pathToSearch` is passed to `R.path`, which means that it can be either a string or an array. Also equality between `target` and the found value is determined by `R.equals`.
15503
15504```javascript
15505const path = 'a.b'
15506const target = {c: 1}
15507const input = {a: {b: {c: 1}}}
15508
15509const result = R.pathEq(
15510 path,
15511 target,
15512 input
15513)
15514// => true
15515```
15516
15517<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20path%20%3D%20'a.b'%0Aconst%20target%20%3D%20%7Bc%3A%201%7D%0Aconst%20input%20%3D%20%7Ba%3A%20%7Bb%3A%20%7Bc%3A%201%7D%7D%7D%0A%0Aconst%20result%20%3D%20R.pathEq(%0A%20%20path%2C%0A%20%20target%2C%0A%20%20input%0A)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.pathEq</strong> example in Rambda REPL</a>
15518
15519<details>
15520
15521<summary>All Typescript definitions</summary>
15522
15523```typescript
15524pathEq(pathToSearch: Path, target: any, input: any): boolean;
15525pathEq(pathToSearch: Path, target: any): (input: any) => boolean;
15526pathEq(pathToSearch: Path): FunctionToolbelt.Curry<(a: any, b: any) => boolean>;
15527```
15528
15529</details>
15530
15531<details>
15532
15533<summary><strong>R.pathEq</strong> source</summary>
15534
15535```javascript
15536import { curry } from './curry'
15537import { equals } from './equals'
15538import { path } from './path'
15539
15540function pathEqFn(
15541 pathToSearch, target, input
15542){
15543 return equals(path(pathToSearch, input), target)
15544}
15545
15546export const pathEq = curry(pathEqFn)
15547```
15548
15549</details>
15550
15551<details>
15552
15553<summary><strong>Tests</strong></summary>
15554
15555```javascript
15556import { pathEq } from './pathEq'
15557
15558test('when true', () => {
15559 const path = 'a.b'
15560 const obj = { a : { b : { c : 1 } } }
15561 const target = { c : 1 }
15562
15563 expect(pathEq(
15564 path, target, obj
15565 )).toBeTrue()
15566})
15567
15568test('when false', () => {
15569 const path = 'a.b'
15570 const obj = { a : { b : 1 } }
15571 const target = 2
15572
15573 expect(pathEq(path, target)(obj)).toBeFalse()
15574})
15575
15576test('when wrong path', () => {
15577 const path = 'foo.bar'
15578 const obj = { a : { b : 1 } }
15579 const target = 2
15580
15581 expect(pathEq(
15582 path, target, obj
15583 )).toBeFalse()
15584})
15585```
15586
15587</details>
15588
15589<details>
15590
15591<summary><strong>Typescript</strong> test</summary>
15592
15593```typescript
15594import {pathEq} from 'rambda'
15595
15596describe('R.pathEq', () => {
15597 it('with string path', () => {
15598 const pathToSearch = 'a.b.c'
15599 const input = {a: {b: {c: 1}}}
15600 const target = {c: 1}
15601
15602 const result = pathEq(pathToSearch, input, target)
15603 const curriedResult = pathEq(pathToSearch, input, target)
15604 result // $ExpectType boolean
15605 curriedResult // $ExpectType boolean
15606 })
15607
15608 it('with array path', () => {
15609 const pathToSearch = ['a', 'b', 'c']
15610 const input = {a: {b: {c: 1}}}
15611 const target = {c: 1}
15612
15613 const result = pathEq(pathToSearch, input, target)
15614 const curriedResult = pathEq(pathToSearch, input, target)
15615 result // $ExpectType boolean
15616 curriedResult // $ExpectType boolean
15617 })
15618})
15619
15620describe('with ramda specs', () => {
15621 const testPath = ['x', 0, 'y']
15622 const testObj = {
15623 x: [
15624 {y: 2, z: 3},
15625 {y: 4, z: 5},
15626 ],
15627 }
15628
15629 const result1 = pathEq(testPath, 2, testObj)
15630 const result2 = pathEq(testPath, 2)(testObj)
15631 const result3 = pathEq(testPath)(2)(testObj)
15632 const result4 = pathEq(testPath)(2, testObj)
15633 result1 // $ExpectType boolean
15634 result2 // $ExpectType boolean
15635 result3 // $ExpectType boolean
15636 result4 // $ExpectType boolean
15637})
15638```
15639
15640</details>
15641
15642*1 failed Ramda.pathEq specs*
15643
15644> :boom: Reason for the failure: Ramda library supports fantasy-land
15645
15646[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pathEq)
15647
15648### pathOr
15649
15650```typescript
15651
15652pathOr<T>(defaultValue: T, pathToSearch: Path, obj: any): T
15653```
15654
15655It reads `obj` input and returns either `R.path(pathToSearch, obj)` result or `defaultValue` input.
15656
15657```javascript
15658const defaultValue = 'DEFAULT_VALUE'
15659const pathToSearch = 'a.b'
15660const pathToSearchList = ['a', 'b']
15661
15662const obj = {
15663 a : {
15664 b : 1
15665 }
15666}
15667
15668const result = [
15669 R.pathOr(DEFAULT_VALUE, pathToSearch, obj)
15670 R.pathOr(DEFAULT_VALUE, pathToSearchList, obj)
15671 R.pathOr(DEFAULT_VALUE, 'a.b.c', obj)
15672]
15673// => [1, 1, 'DEFAULT_VALUE']
15674```
15675
15676<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20defaultValue%20%3D%20'DEFAULT_VALUE'%0Aconst%20pathToSearch%20%3D%20'a.b'%0Aconst%20pathToSearchList%20%3D%20%5B'a'%2C%20'b'%5D%0A%0Aconst%20obj%20%3D%20%7B%0A%20%20a%20%3A%20%7B%0A%20%20%20%20b%20%3A%201%0A%20%20%7D%0A%7D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.pathOr(DEFAULT_VALUE%2C%20pathToSearch%2C%20obj)%20%0A%20%20R.pathOr(DEFAULT_VALUE%2C%20pathToSearchList%2C%20obj)%20%0A%20%20R.pathOr(DEFAULT_VALUE%2C%20'a.b.c'%2C%20obj)%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B1%2C%201%2C%20'DEFAULT_VALUE'%5D">Try this <strong>R.pathOr</strong> example in Rambda REPL</a>
15677
15678<details>
15679
15680<summary>All Typescript definitions</summary>
15681
15682```typescript
15683pathOr<T>(defaultValue: T, pathToSearch: Path, obj: any): T;
15684pathOr<T>(defaultValue: T, pathToSearch: Path): (obj: any) => T;
15685pathOr<T>(defaultValue: T): FunctionToolbelt.Curry<(a: Path, b: any) => T>;
15686```
15687
15688</details>
15689
15690<details>
15691
15692<summary><strong>R.pathOr</strong> source</summary>
15693
15694```javascript
15695import { curry } from './curry'
15696import { defaultTo } from './defaultTo'
15697import { path } from './path'
15698
15699function pathOrFn(
15700 defaultValue, list, obj
15701){
15702 return defaultTo(defaultValue, path(list, obj))
15703}
15704
15705export const pathOr = curry(pathOrFn)
15706```
15707
15708</details>
15709
15710<details>
15711
15712<summary><strong>Tests</strong></summary>
15713
15714```javascript
15715import { pathOr } from './pathOr'
15716
15717test('with undefined', () => {
15718 const result = pathOr(
15719 'foo', 'x.y', { x : { y : 1 } }
15720 )
15721
15722 expect(result).toEqual(1)
15723})
15724
15725test('with null', () => {
15726 const result = pathOr(
15727 'foo', 'x.y', null
15728 )
15729
15730 expect(result).toEqual('foo')
15731})
15732
15733test('with NaN', () => {
15734 const result = pathOr(
15735 'foo', 'x.y', NaN
15736 )
15737
15738 expect(result).toEqual('foo')
15739})
15740
15741test('curry case (x)(y)(z)', () => {
15742 const result = pathOr('foo')('x.y.z')({ x : { y : { a : 1 } } })
15743
15744 expect(result).toEqual('foo')
15745})
15746
15747test('curry case (x)(y,z)', () => {
15748 const result = pathOr('foo', 'x.y.z')({ x : { y : { a : 1 } } })
15749
15750 expect(result).toEqual('foo')
15751})
15752
15753test('curry case (x,y)(z)', () => {
15754 const result = pathOr('foo')('x.y.z', { x : { y : { a : 1 } } })
15755
15756 expect(result).toEqual('foo')
15757})
15758```
15759
15760</details>
15761
15762<details>
15763
15764<summary><strong>Typescript</strong> test</summary>
15765
15766```typescript
15767import {pathOr} from 'rambda'
15768
15769describe('R.pathOr', () => {
15770 it('with string path', () => {
15771 const x = pathOr<string>('foo', 'x.y', {x: {y: 'bar'}})
15772 x // $ExpectType string
15773 })
15774 it('with array path', () => {
15775 const x = pathOr<string>('foo', ['x', 'y'], {x: {y: 'bar'}})
15776 x // $ExpectType string
15777 })
15778 it('without passing type looks bad', () => {
15779 const x = pathOr('foo', 'x.y', {x: {y: 'bar'}})
15780 x // $ExpectType "foo"
15781 })
15782 it('curried', () => {
15783 const x = pathOr<string>('foo', 'x.y')({x: {y: 'bar'}})
15784 x // $ExpectType string
15785 })
15786})
15787```
15788
15789</details>
15790
15791[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pathOr)
15792
15793### paths
15794
15795```typescript
15796
15797paths<Input, T>(pathsToSearch: Path[], obj: Input): (T | undefined)[]
15798```
15799
15800It loops over members of `pathsToSearch` as `singlePath` and returns the array produced by `R.path(singlePath, obj)`.
15801
15802Because it calls `R.path`, then `singlePath` can be either string or a list.
15803
15804```javascript
15805const obj = {
15806 a : {
15807 b : {
15808 c : 1,
15809 d : 2
15810 }
15811 }
15812}
15813
15814const result = R.paths([
15815 'a.b.c',
15816 'a.b.c.d',
15817 'a.b.c.d.e',
15818], obj)
15819// => [1, 2, undefined]
15820```
15821
15822<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7B%0A%20%20a%20%3A%20%7B%0A%20%20%20%20b%20%3A%20%7B%0A%20%20%20%20%20%20c%20%3A%201%2C%0A%20%20%20%20%20%20d%20%3A%202%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0Aconst%20result%20%3D%20R.paths(%5B%0A%20%20'a.b.c'%2C%0A%20%20'a.b.c.d'%2C%0A%20%20'a.b.c.d.e'%2C%0A%5D%2C%20obj)%0A%2F%2F%20%3D%3E%20%5B1%2C%202%2C%20undefined%5D">Try this <strong>R.paths</strong> example in Rambda REPL</a>
15823
15824<details>
15825
15826<summary>All Typescript definitions</summary>
15827
15828```typescript
15829paths<Input, T>(pathsToSearch: Path[], obj: Input): (T | undefined)[];
15830paths<Input, T>(pathsToSearch: Path[]): (obj: Input) => (T | undefined)[];
15831paths<T>(pathsToSearch: Path[], obj: any): (T | undefined)[];
15832paths<T>(pathsToSearch: Path[]): (obj: any) => (T | undefined)[];
15833```
15834
15835</details>
15836
15837<details>
15838
15839<summary><strong>R.paths</strong> source</summary>
15840
15841```javascript
15842import { path } from './path'
15843
15844export function paths(pathsToSearch, obj){
15845 if (arguments.length === 1){
15846 return _obj => paths(pathsToSearch, _obj)
15847 }
15848
15849 return pathsToSearch.map(singlePath => path(singlePath, obj))
15850}
15851```
15852
15853</details>
15854
15855<details>
15856
15857<summary><strong>Tests</strong></summary>
15858
15859```javascript
15860import { paths } from './paths'
15861
15862const obj = {
15863 a : {
15864 b : {
15865 c : 1,
15866 d : 2,
15867 },
15868 },
15869 p : [ { q : 3 } ],
15870 x : {
15871 y : 'FOO',
15872 z : [ [ {} ] ],
15873 },
15874}
15875
15876test('with string path + curry', () => {
15877 const pathsInput = [ 'a.b.d', 'p.q' ]
15878 const expected = [ 2, undefined ]
15879 const result = paths(pathsInput, obj)
15880 const curriedResult = paths(pathsInput)(obj)
15881
15882 expect(result).toEqual(expected)
15883 expect(curriedResult).toEqual(expected)
15884})
15885
15886test('with array path', () => {
15887 const result = paths([
15888 [ 'a', 'b', 'c' ],
15889 [ 'x', 'y' ],
15890 ],
15891 obj)
15892
15893 expect(result).toEqual([ 1, 'FOO' ])
15894})
15895
15896test('takes a paths that contains indices into arrays', () => {
15897 expect(paths([
15898 [ 'p', 0, 'q' ],
15899 [ 'x', 'z', 0, 0 ],
15900 ],
15901 obj)).toEqual([ 3, {} ])
15902 expect(paths([
15903 [ 'p', 0, 'q' ],
15904 [ 'x', 'z', 2, 1 ],
15905 ],
15906 obj)).toEqual([ 3, undefined ])
15907})
15908
15909test('gets a deep property\'s value from objects', () => {
15910 expect(paths([ [ 'a', 'b' ] ], obj)).toEqual([ obj.a.b ])
15911 expect(paths([ [ 'p', 0 ] ], obj)).toEqual([ obj.p[ 0 ] ])
15912})
15913
15914test('returns undefined for items not found', () => {
15915 expect(paths([ [ 'a', 'x', 'y' ] ], obj)).toEqual([ undefined ])
15916 expect(paths([ [ 'p', 2 ] ], obj)).toEqual([ undefined ])
15917})
15918```
15919
15920</details>
15921
15922<details>
15923
15924<summary><strong>Typescript</strong> test</summary>
15925
15926```typescript
15927import {paths} from 'rambda'
15928
15929interface Input {
15930 a: number,
15931 b: number,
15932 c: number,
15933}
15934
15935const input: Input = {a: 1, b: 2, c: 3}
15936
15937describe('R.paths', () => {
15938 it('with dot notation', () => {
15939 const result = paths<number>(['a.b.c', 'foo.bar'], input)
15940 result // $ExpectType (number | undefined)[]
15941 })
15942
15943 it('without type', () => {
15944 const result = paths(['a.b.c', 'foo.bar'], input)
15945 result // $ExpectType unknown[]
15946 })
15947
15948 it('with array as path', () => {
15949 const result = paths<number>([['a', 'b', 'c'], ['foo.bar']], input)
15950 result // $ExpectType (number | undefined)[]
15951 })
15952
15953 it('curried', () => {
15954 const result = paths<number>([['a', 'b', 'c'], ['foo.bar']])(input)
15955 result // $ExpectType (number | undefined)[]
15956 })
15957})
15958```
15959
15960</details>
15961
15962<details>
15963
15964<summary>1 failed <italic>Ramda.paths</italic> specs
15965
15966> :boom: Reason for the failure: Ramda method supports negative indexes
15967</summary>
15968
15969```javascript
15970var R = require('../../../../dist/rambda.js');
15971var eq = require('./shared/eq');
15972
15973describe('paths', function() {
15974 var obj = {
15975 a: {
15976 b: {
15977 c: 1,
15978 d: 2
15979 }
15980 },
15981 p: [{q: 3}, 'Hi'],
15982 x: {
15983 y: 'Alice',
15984 z: [[{}]]
15985 }
15986 };
15987 it('takes a path that contains negative indices into arrays', function() {
15988 eq(R.paths([['p', -2, 'q'], ['p', -1]], obj), [3, 'Hi']);
15989 eq(R.paths([['p', -4, 'q'], ['x', 'z', -1, 0]], obj), [undefined, {}]);
15990 });
15991});
15992```
15993
15994</details>
15995
15996[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#paths)
15997
15998### pick
15999
16000```typescript
16001
16002pick<T, K extends string | number | symbol>(propsToPick: readonly K[], input: T): Pick<T, Exclude<keyof T, Exclude<keyof T, K>>>
16003```
16004
16005It returns a partial copy of an `input` containing only `propsToPick` properties.
16006
16007`input` can be either an object or an array.
16008
16009String anotation of `propsToPick` is one of the differences between `Rambda` and `Ramda`.
16010
16011> :boom: When using this method with `TypeScript`, it is much easier to pass `propsToPick` as an array. If passing a string, you will need to explicitly declare the output type.
16012
16013```javascript
16014const obj = {
16015 a : 1,
16016 b : false,
16017 foo: 'cherry'
16018}
16019const list = [1, 2, 3, 4]
16020const propsToPick = 'a,foo'
16021const propsToPickList = ['a', 'foo']
16022
16023const result = [
16024 R.pick(propsToPick, obj),
16025 R.pick(propsToPickList, obj),
16026 R.pick('a,bar', obj),
16027 R.pick('bar', obj),
16028 R.pick([0, 3], list),
16029 R.pick('0,3', list),
16030]
16031
16032const expected = [
16033 {a:1, foo: 'cherry'},
16034 {a:1, foo: 'cherry'},
16035 {a:1},
16036 {},
16037 [1,4],
16038 [1,4]
16039]
16040// => `result` is equal to `expected`
16041```
16042
16043<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%20false%2C%0A%20%20foo%3A%20'cherry'%0A%7D%0Aconst%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%5D%0Aconst%20propsToPick%20%3D%20'a%2Cfoo'%0Aconst%20propsToPickList%20%3D%20%5B'a'%2C%20'foo'%5D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.pick(propsToPick%2C%20obj)%2C%0A%20%20R.pick(propsToPickList%2C%20obj)%2C%0A%20%20R.pick('a%2Cbar'%2C%20obj)%2C%0A%20%20R.pick('bar'%2C%20obj)%2C%0A%20%20R.pick(%5B0%2C%203%5D%2C%20list)%2C%0A%20%20R.pick('0%2C3'%2C%20list)%2C%0A%5D%0A%0Aconst%20expected%20%3D%20%5B%0A%20%20%7Ba%3A1%2C%20foo%3A%20'cherry'%7D%2C%0A%20%20%7Ba%3A1%2C%20foo%3A%20'cherry'%7D%2C%0A%20%20%7Ba%3A1%7D%2C%0A%20%20%7B%7D%2C%0A%20%20%5B1%2C4%5D%2C%0A%20%20%5B1%2C4%5D%0A%5D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.pick</strong> example in Rambda REPL</a>
16044
16045<details>
16046
16047<summary>All Typescript definitions</summary>
16048
16049```typescript
16050pick<T, K extends string | number | symbol>(propsToPick: readonly K[], input: T): Pick<T, Exclude<keyof T, Exclude<keyof T, K>>>;
16051pick<K extends string | number | symbol>(propsToPick: readonly K[]): <T>(input: T) => Pick<T, Exclude<keyof T, Exclude<keyof T, K>>>;
16052pick<T, U>(propsToPick: string, input: T): U;
16053pick<T, U>(propsToPick: string): (input: T) => U;
16054pick<T>(propsToPick: string, input: object): T;
16055pick<T>(propsToPick: string): (input: object) => T;
16056```
16057
16058</details>
16059
16060<details>
16061
16062<summary><strong>R.pick</strong> source</summary>
16063
16064```javascript
16065export function pick(propsToPick, input){
16066 if (arguments.length === 1) return _input => pick(propsToPick, _input)
16067
16068 if (input === null || input === undefined){
16069 return undefined
16070 }
16071 const keys =
16072 typeof propsToPick === 'string' ? propsToPick.split(',') : propsToPick
16073
16074 const willReturn = {}
16075 let counter = 0
16076
16077 while (counter < keys.length){
16078 if (keys[ counter ] in input){
16079 willReturn[ keys[ counter ] ] = input[ keys[ counter ] ]
16080 }
16081 counter++
16082 }
16083
16084 return willReturn
16085}
16086```
16087
16088</details>
16089
16090<details>
16091
16092<summary><strong>Tests</strong></summary>
16093
16094```javascript
16095import { pick } from './pick'
16096
16097const obj = {
16098 a : 1,
16099 b : 2,
16100 c : 3,
16101}
16102
16103test('props to pick is a string', () => {
16104 const result = pick('a,c', obj)
16105 const resultCurry = pick('a,c')(obj)
16106 const expectedResult = {
16107 a : 1,
16108 c : 3,
16109 }
16110
16111 expect(result).toEqual(expectedResult)
16112 expect(resultCurry).toEqual(expectedResult)
16113})
16114
16115test('when prop is missing', () => {
16116 const result = pick('a,d,f', obj)
16117 expect(result).toEqual({ a : 1 })
16118})
16119
16120test('props to pick is an array', () => {
16121 expect(pick([ 'a', 'c' ])({
16122 a : 'foo',
16123 b : 'bar',
16124 c : 'baz',
16125 })).toEqual({
16126 a : 'foo',
16127 c : 'baz',
16128 })
16129
16130 expect(pick([ 'a', 'd', 'e', 'f' ])({
16131 a : 'foo',
16132 b : 'bar',
16133 c : 'baz',
16134 })).toEqual({ a : 'foo' })
16135
16136 expect(pick('a,d,e,f')(null)).toEqual(undefined)
16137})
16138
16139test('works with list as input and number as props - props to pick is an array', () => {
16140 const result = pick([ 1, 2 ], [ 'a', 'b', 'c', 'd' ])
16141 expect(result).toEqual({
16142 1 : 'b',
16143 2 : 'c',
16144 })
16145})
16146
16147test('works with list as input and number as props - props to pick is a string', () => {
16148 const result = pick('1,2', [ 'a', 'b', 'c', 'd' ])
16149 expect(result).toEqual({
16150 1 : 'b',
16151 2 : 'c',
16152 })
16153})
16154
16155test('with symbol', () => {
16156 const symbolProp = Symbol('s')
16157 expect(pick([ symbolProp ], { [ symbolProp ] : 'a' })).toMatchInlineSnapshot(`
16158 Object {
16159 Symbol(s): "a",
16160 }
16161 `)
16162})
16163```
16164
16165</details>
16166
16167<details>
16168
16169<summary><strong>Typescript</strong> test</summary>
16170
16171```typescript
16172import {pick} from 'rambda'
16173
16174const input = {a: 'foo', b: 2, c: 3, d: 4}
16175
16176describe('R.pick with array as props input', () => {
16177 it('without passing type', () => {
16178 const result = pick(['a', 'c'], input)
16179 result.a // $ExpectType string
16180 result.c // $ExpectType number
16181 })
16182})
16183
16184describe('R.pick with string as props input', () => {
16185 interface Input {
16186 a: string,
16187 b: number,
16188 c: number,
16189 d: number,
16190 }
16191 interface Output {
16192 a: string,
16193 c: number,
16194 }
16195 it('explicitly declare output', () => {
16196 const result = pick<Output>('a,c', input)
16197 result // $ExpectType Output
16198 result.a // $ExpectType string
16199 result.c // $ExpectType number
16200
16201 const curriedResult = pick<Output>('a,c')(input)
16202
16203 curriedResult.a // $ExpectType string
16204 })
16205
16206 it('explicitly declare input and output', () => {
16207 const result = pick<Input, Output>('a,c', input)
16208 result // $ExpectType Output
16209 result.a // $ExpectType string
16210
16211 const curriedResult = pick<Input, Output>('a,c')(input)
16212
16213 curriedResult.a // $ExpectType string
16214 })
16215
16216 it('without passing type', () => {
16217 const result = pick('a,c', input)
16218 result // $ExpectType unknown
16219 })
16220})
16221```
16222
16223</details>
16224
16225[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pick)
16226
16227### pickAll
16228
16229```typescript
16230
16231pickAll<T, U>(propsToPick: readonly string[], input: T): U
16232```
16233
16234Same as `R.pick` but it won't skip the missing props, i.e. it will assign them to `undefined`.
16235
16236> :boom: When using this method with `TypeScript`, it is much easier to pass `propsToPick` as an array. If passing a string, you will need to explicitly declare the output type.
16237
16238```javascript
16239const obj = {
16240 a : 1,
16241 b : false,
16242 foo: 'cherry'
16243}
16244const propsToPick = 'a,foo,bar'
16245const propsToPickList = ['a', 'foo', 'bar']
16246
16247const result = [
16248 R.pickAll(propsToPick, obj),
16249 R.pickAll(propsToPickList, obj),
16250 R.pickAll('a,bar', obj),
16251 R.pickAll('bar', obj),
16252]
16253const expected = [
16254 {a:1, foo: 'cherry', bar: undefined},
16255 {a:1, foo: 'cherry', bar: undefined},
16256 {a:1, bar: undefined},
16257 {bar: undefined}
16258]
16259// => `result` is equal to `expected`
16260```
16261
16262<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%20false%2C%0A%20%20foo%3A%20'cherry'%0A%7D%0Aconst%20propsToPick%20%3D%20'a%2Cfoo%2Cbar'%0Aconst%20propsToPickList%20%3D%20%5B'a'%2C%20'foo'%2C%20'bar'%5D%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.pickAll(propsToPick%2C%20obj)%2C%0A%20%20R.pickAll(propsToPickList%2C%20obj)%2C%0A%20%20R.pickAll('a%2Cbar'%2C%20obj)%2C%0A%20%20R.pickAll('bar'%2C%20obj)%2C%0A%5D%0Aconst%20expected%20%3D%20%5B%0A%20%20%7Ba%3A1%2C%20foo%3A%20'cherry'%2C%20bar%3A%20undefined%7D%2C%0A%20%20%7Ba%3A1%2C%20foo%3A%20'cherry'%2C%20bar%3A%20undefined%7D%2C%0A%20%20%7Ba%3A1%2C%20bar%3A%20undefined%7D%2C%0A%20%20%7Bbar%3A%20undefined%7D%0A%5D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.pickAll</strong> example in Rambda REPL</a>
16263
16264<details>
16265
16266<summary>All Typescript definitions</summary>
16267
16268```typescript
16269pickAll<T, U>(propsToPick: readonly string[], input: T): U;
16270pickAll<T, U>(propsToPick: readonly string[]): (input: T) => U;
16271pickAll<T, U>(propsToPick: string, input: T): U;
16272pickAll<T, U>(propsToPick: string): (input: T) => U;
16273```
16274
16275</details>
16276
16277<details>
16278
16279<summary><strong>R.pickAll</strong> source</summary>
16280
16281```javascript
16282export function pickAll(propsToPick, obj){
16283 if (arguments.length === 1) return _obj => pickAll(propsToPick, _obj)
16284
16285 if (obj === null || obj === undefined){
16286 return undefined
16287 }
16288 const keysValue =
16289 typeof propsToPick === 'string' ? propsToPick.split(',') : propsToPick
16290
16291 const willReturn = {}
16292 let counter = 0
16293
16294 while (counter < keysValue.length){
16295 if (keysValue[ counter ] in obj){
16296 willReturn[ keysValue[ counter ] ] = obj[ keysValue[ counter ] ]
16297 } else {
16298 willReturn[ keysValue[ counter ] ] = undefined
16299 }
16300 counter++
16301 }
16302
16303 return willReturn
16304}
16305```
16306
16307</details>
16308
16309<details>
16310
16311<summary><strong>Tests</strong></summary>
16312
16313```javascript
16314import { pickAll } from './pickAll'
16315
16316test('when input is undefined or null', () => {
16317 expect(pickAll('a', null)).toBe(undefined)
16318 expect(pickAll('a', undefined)).toBe(undefined)
16319})
16320
16321test('with string as condition', () => {
16322 const obj = {
16323 a : 1,
16324 b : 2,
16325 c : 3,
16326 }
16327 const result = pickAll('a,c', obj)
16328 const resultCurry = pickAll('a,c')(obj)
16329 const expectedResult = {
16330 a : 1,
16331 b : undefined,
16332 c : 3,
16333 }
16334
16335 expect(result).toEqual(expectedResult)
16336 expect(resultCurry).toEqual(expectedResult)
16337})
16338
16339test('with array as condition', () => {
16340 expect(pickAll([ 'a', 'b', 'c' ], {
16341 a : 'foo',
16342 c : 'baz',
16343 })).toEqual({
16344 a : 'foo',
16345 b : undefined,
16346 c : 'baz',
16347 })
16348})
16349```
16350
16351</details>
16352
16353<details>
16354
16355<summary><strong>Typescript</strong> test</summary>
16356
16357```typescript
16358import {pickAll} from 'rambda'
16359
16360interface Input {
16361 a: string,
16362 b: number,
16363 c: number,
16364 d: number,
16365}
16366interface Output {
16367 a?: string,
16368 c?: number,
16369}
16370const input = {a: 'foo', b: 2, c: 3, d: 4}
16371
16372describe('R.pickAll with array as props input', () => {
16373 it('without passing type', () => {
16374 const result = pickAll(['a', 'c'], input)
16375 result // $ExpectType unknown
16376 })
16377 it('without passing type + curry', () => {
16378 const result = pickAll(['a', 'c'])(input)
16379 result // $ExpectType unknown
16380 })
16381 it('explicitly passing types', () => {
16382 const result = pickAll<Input, Output>(['a', 'c'], input)
16383 result.a // $ExpectType string | undefined
16384 result.c // $ExpectType number | undefined
16385 })
16386 it('explicitly passing types + curry', () => {
16387 const result = pickAll<Input, Output>(['a', 'c'])(input)
16388 result.a // $ExpectType string | undefined
16389 result.c // $ExpectType number | undefined
16390 })
16391})
16392
16393describe('R.pickAll with string as props input', () => {
16394 it('without passing type', () => {
16395 const result = pickAll('a,c', input)
16396 result // $ExpectType unknown
16397 })
16398 it('without passing type + curry', () => {
16399 const result = pickAll('a,c')(input)
16400 result // $ExpectType unknown
16401 })
16402 it('explicitly passing types', () => {
16403 const result = pickAll<Input, Output>('a,c', input)
16404 result.a // $ExpectType string | undefined
16405 result.c // $ExpectType number | undefined
16406 })
16407 it('explicitly passing types + curry', () => {
16408 const result = pickAll<Input, Output>('a,c')(input)
16409 result.a // $ExpectType string | undefined
16410 result.c // $ExpectType number | undefined
16411 })
16412})
16413```
16414
16415</details>
16416
16417[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pickAll)
16418
16419### pipe
16420
16421```typescript
16422
16423pipe<T1>(fn0: () => T1): () => T1
16424```
16425
16426It performs left-to-right function composition.
16427
16428```javascript
16429const result = R.pipe(
16430 R.filter(val => val > 2),
16431 R.map(a => a * 2)
16432)([1, 2, 3, 4])
16433
16434// => [6, 8]
16435```
16436
16437<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.pipe(%0A%20%20R.filter(val%20%3D%3E%20val%20%3E%202)%2C%0A%20%20R.map(a%20%3D%3E%20a%20*%202)%0A)(%5B1%2C%202%2C%203%2C%204%5D)%0A%0A%2F%2F%20%3D%3E%20%5B6%2C%208%5D">Try this <strong>R.pipe</strong> example in Rambda REPL</a>
16438
16439<details>
16440
16441<summary>All Typescript definitions</summary>
16442
16443```typescript
16444pipe<T1>(fn0: () => T1): () => T1;
16445pipe<V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1;
16446pipe<V0, V1, T1>(fn0: (x0: V0, x1: V1) => T1): (x0: V0, x1: V1) => T1;
16447pipe<V0, V1, V2, T1>(fn0: (x0: V0, x1: V1, x2: V2) => T1): (x0: V0, x1: V1, x2: V2) => T1;
16448
16449pipe<T1, T2>(fn0: () => T1, fn1: (x: T1) => T2): () => T2;
16450pipe<V0, T1, T2>(fn0: (x0: V0) => T1, fn1: (x: T1) => T2): (x0: V0) => T2;
16451pipe<V0, V1, T1, T2>(fn0: (x0: V0, x1: V1) => T1, fn1: (x: T1) => T2): (x0: V0, x1: V1) => T2;
16452pipe<V0, V1, V2, T1, T2>(fn0: (x0: V0, x1: V1, x2: V2) => T1, fn1: (x: T1) => T2): (x0: V0, x1: V1, x2: V2) => T2;
16453
16454pipe<T1, T2, T3>(fn0: () => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3): () => T3;
16455pipe<V0, T1, T2, T3>(fn0: (x: V0) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3): (x: V0) => T3;
16456pipe<V0, V1, T1, T2, T3>(fn0: (x0: V0, x1: V1) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3): (x0: V0, x1: V1) => T3;
16457pipe<V0, V1, V2, T1, T2, T3>(fn0: (x0: V0, x1: V1, x2: V2) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3): (x0: V0, x1: V1, x2: V2) => T3;
16458
16459pipe<T1, T2, T3, T4>(fn0: () => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4): () => T4;
16460pipe<V0, T1, T2, T3, T4>(fn0: (x: V0) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4): (x: V0) => T4;
16461pipe<V0, V1, T1, T2, T3, T4>(fn0: (x0: V0, x1: V1) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4): (x0: V0, x1: V1) => T4;
16462pipe<V0, V1, V2, T1, T2, T3, T4>(fn0: (x0: V0, x1: V1, x2: V2) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4): (x0: V0, x1: V1, x2: V2) => T4;
16463
16464pipe<T1, T2, T3, T4, T5>(fn0: () => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5): () => T5;
16465pipe<V0, T1, T2, T3, T4, T5>(fn0: (x: V0) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5): (x: V0) => T5;
16466pipe<V0, V1, T1, T2, T3, T4, T5>(fn0: (x0: V0, x1: V1) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5): (x0: V0, x1: V1) => T5;
16467pipe<V0, V1, V2, T1, T2, T3, T4, T5>(fn0: (x0: V0, x1: V1, x2: V2) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5): (x0: V0, x1: V1, x2: V2) => T5;
16468
16469pipe<T1, T2, T3, T4, T5, T6>(fn0: () => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5, fn5: (x: T5) => T6): () => T6;
16470pipe<V0, T1, T2, T3, T4, T5, T6>(fn0: (x: V0) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5, fn5: (x: T5) => T6): (x: V0) => T6;
16471pipe<V0, V1, T1, T2, T3, T4, T5, T6>(fn0: (x0: V0, x1: V1) => T1, fn1: (x: T1) => T2, fn2: (x: T2) => T3, fn3: (x: T3) => T4, fn4: (x: T4) => T5, fn5: (x: T5) => T6): (x0: V0, x1: V1) => T6;
16472pipe<V0, V1, V2, T1, T2, T3, T4, T5, T6>(
16473 fn0: (x0: V0, x1: V1, x2: V2) => T1,
16474 fn1: (x: T1) => T2,
16475 fn2: (x: T2) => T3,
16476 fn3: (x: T3) => T4,
16477 fn4: (x: T4) => T5,
16478 fn5: (x: T5) => T6): (x0: V0, x1: V1, x2: V2) => T6;
16479
16480pipe<T1, T2, T3, T4, T5, T6, T7>(
16481 fn0: () => T1,
16482 fn1: (x: T1) => T2,
16483 fn2: (x: T2) => T3,
16484 fn3: (x: T3) => T4,
16485 fn4: (x: T4) => T5,
16486 fn5: (x: T5) => T6,
16487 fn: (x: T6) => T7): () => T7;
16488pipe<V0, T1, T2, T3, T4, T5, T6, T7>(
16489 fn0: (x: V0) => T1,
16490 fn1: (x: T1) => T2,
16491 fn2: (x: T2) => T3,
16492 fn3: (x: T3) => T4,
16493 fn4: (x: T4) => T5,
16494 fn5: (x: T5) => T6,
16495 fn: (x: T6) => T7): (x: V0) => T7;
16496pipe<V0, V1, T1, T2, T3, T4, T5, T6, T7>(
16497 fn0: (x0: V0, x1: V1) => T1,
16498 fn1: (x: T1) => T2,
16499 fn2: (x: T2) => T3,
16500 fn3: (x: T3) => T4,
16501 fn4: (x: T4) => T5,
16502 fn5: (x: T5) => T6,
16503 fn6: (x: T6) => T7): (x0: V0, x1: V1) => T7;
16504pipe<V0, V1, V2, T1, T2, T3, T4, T5, T6, T7>(
16505 fn0: (x0: V0, x1: V1, x2: V2) => T1,
16506 fn1: (x: T1) => T2,
16507 fn2: (x: T2) => T3,
16508 fn3: (x: T3) => T4,
16509 fn4: (x: T4) => T5,
16510 fn5: (x: T5) => T6,
16511 fn6: (x: T6) => T7): (x0: V0, x1: V1, x2: V2) => T7;
16512
16513pipe<T1, T2, T3, T4, T5, T6, T7, T8>(
16514 fn0: () => T1,
16515 fn1: (x: T1) => T2,
16516 fn2: (x: T2) => T3,
16517 fn3: (x: T3) => T4,
16518 fn4: (x: T4) => T5,
16519 fn5: (x: T5) => T6,
16520 fn6: (x: T6) => T7,
16521 fn: (x: T7) => T8): () => T8;
16522pipe<V0, T1, T2, T3, T4, T5, T6, T7, T8>(
16523 fn0: (x: V0) => T1,
16524 fn1: (x: T1) => T2,
16525 fn2: (x: T2) => T3,
16526 fn3: (x: T3) => T4,
16527 fn4: (x: T4) => T5,
16528 fn5: (x: T5) => T6,
16529 fn6: (x: T6) => T7,
16530 fn: (x: T7) => T8): (x: V0) => T8;
16531pipe<V0, V1, T1, T2, T3, T4, T5, T6, T7, T8>(
16532 fn0: (x0: V0, x1: V1) => T1,
16533 fn1: (x: T1) => T2,
16534 fn2: (x: T2) => T3,
16535 fn3: (x: T3) => T4,
16536 fn4: (x: T4) => T5,
16537 fn5: (x: T5) => T6,
16538 fn6: (x: T6) => T7,
16539 fn7: (x: T7) => T8): (x0: V0, x1: V1) => T8;
16540pipe<V0, V1, V2, T1, T2, T3, T4, T5, T6, T7, T8>(
16541 fn0: (x0: V0, x1: V1, x2: V2) => T1,
16542 fn1: (x: T1) => T2,
16543 fn2: (x: T2) => T3,
16544 fn3: (x: T3) => T4,
16545 fn4: (x: T4) => T5,
16546 fn5: (x: T5) => T6,
16547 fn6: (x: T6) => T7,
16548 fn7: (x: T7) => T8): (x0: V0, x1: V1, x2: V2) => T8;
16549
16550pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
16551 fn0: () => T1,
16552 fn1: (x: T1) => T2,
16553 fn2: (x: T2) => T3,
16554 fn3: (x: T3) => T4,
16555 fn4: (x: T4) => T5,
16556 fn5: (x: T5) => T6,
16557 fn6: (x: T6) => T7,
16558 fn7: (x: T7) => T8,
16559 fn8: (x: T8) => T9): () => T9;
16560pipe<V0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
16561 fn0: (x0: V0) => T1,
16562 fn1: (x: T1) => T2,
16563 fn2: (x: T2) => T3,
16564 fn3: (x: T3) => T4,
16565 fn4: (x: T4) => T5,
16566 fn5: (x: T5) => T6,
16567 fn6: (x: T6) => T7,
16568 fn7: (x: T7) => T8,
16569 fn8: (x: T8) => T9): (x0: V0) => T9;
16570pipe<V0, V1, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
16571 fn0: (x0: V0, x1: V1) => T1,
16572 fn1: (x: T1) => T2,
16573 fn2: (x: T2) => T3,
16574 fn3: (x: T3) => T4,
16575 fn4: (x: T4) => T5,
16576 fn5: (x: T5) => T6,
16577 fn6: (x: T6) => T7,
16578 fn7: (x: T7) => T8,
16579 fn8: (x: T8) => T9): (x0: V0, x1: V1) => T9;
16580pipe<V0, V1, V2, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
16581 fn0: (x0: V0, x1: V1, x2: V2) => T1,
16582 fn1: (x: T1) => T2,
16583 fn2: (x: T2) => T3,
16584 fn3: (x: T3) => T4,
16585 fn4: (x: T4) => T5,
16586 fn5: (x: T5) => T6,
16587 fn6: (x: T6) => T7,
16588 fn7: (x: T7) => T8,
16589 fn8: (x: T8) => T9): (x0: V0, x1: V1, x2: V2) => T9;
16590
16591pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
16592 fn0: () => T1,
16593 fn1: (x: T1) => T2,
16594 fn2: (x: T2) => T3,
16595 fn3: (x: T3) => T4,
16596 fn4: (x: T4) => T5,
16597 fn5: (x: T5) => T6,
16598 fn6: (x: T6) => T7,
16599 fn7: (x: T7) => T8,
16600 fn8: (x: T8) => T9,
16601 fn9: (x: T9) => T10): () => T10;
16602pipe<V0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
16603 fn0: (x0: V0) => T1,
16604 fn1: (x: T1) => T2,
16605 fn2: (x: T2) => T3,
16606 fn3: (x: T3) => T4,
16607 fn4: (x: T4) => T5,
16608 fn5: (x: T5) => T6,
16609 fn6: (x: T6) => T7,
16610 fn7: (x: T7) => T8,
16611 fn8: (x: T8) => T9,
16612 fn9: (x: T9) => T10): (x0: V0) => T10;
16613pipe<V0, V1, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
16614 fn0: (x0: V0, x1: V1) => T1,
16615 fn1: (x: T1) => T2,
16616 fn2: (x: T2) => T3,
16617 fn3: (x: T3) => T4,
16618 fn4: (x: T4) => T5,
16619 fn5: (x: T5) => T6,
16620 fn6: (x: T6) => T7,
16621 fn7: (x: T7) => T8,
16622 fn8: (x: T8) => T9,
16623 fn9: (x: T9) => T10): (x0: V0, x1: V1) => T10;
16624pipe<V0, V1, V2, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
16625 fn0: (x0: V0, x1: V1, x2: V2) => T1,
16626 fn1: (x: T1) => T2,
16627 fn2: (x: T2) => T3,
16628 fn3: (x: T3) => T4,
16629 fn4: (x: T4) => T5,
16630 fn5: (x: T5) => T6,
16631 fn6: (x: T6) => T7,
16632 fn7: (x: T7) => T8,
16633 fn8: (x: T8) => T9,
16634 fn9: (x: T9) => T10): (x0: V0, x1: V1, x2: V2) => T10;
16635```
16636
16637</details>
16638
16639<details>
16640
16641<summary><strong>R.pipe</strong> source</summary>
16642
16643```javascript
16644import { compose } from './compose'
16645
16646export function pipe(...fns){
16647 if (fns.length === 0)
16648 throw new Error('pipe requires at least one argument')
16649
16650 return compose(...fns.reverse())
16651}
16652```
16653
16654</details>
16655
16656<details>
16657
16658<summary><strong>Tests</strong></summary>
16659
16660```javascript
16661import { add, last, map } from '../rambda'
16662import { pipe } from './pipe'
16663
16664test('happy', () => {
16665 const list = [ 1, 2, 3 ]
16666
16667 const result = pipe(
16668 map(add(1)), map(add(10)), last
16669 )(list)
16670
16671 expect(result).toEqual(14)
16672})
16673
16674test('with bad input', () => {
16675 expect(() => pipe()).toThrowWithMessage(Error,
16676 'pipe requires at least one argument')
16677})
16678```
16679
16680</details>
16681
16682<details>
16683
16684<summary><strong>Typescript</strong> test</summary>
16685
16686```typescript
16687import {add, subtract, pipe} from 'rambda'
16688
16689describe('R.pipe', () => {
16690 it('happy', () => {
16691 const result = pipe(subtract(11), add(1), add(1))(1)
16692 result // $ExpectType number
16693 })
16694
16695 it('with void', () => {
16696 const result = pipe(
16697 () => {},
16698 () => {}
16699 )()
16700 result // $ExpectType void
16701 })
16702})
16703```
16704
16705</details>
16706
16707<details>
16708
16709<summary>3 failed <italic>Ramda.pipe</italic> specs
16710
16711> :boom: Reason for the failure: Ramda method passes context to functions | Rambda composed functions have no length
16712</summary>
16713
16714```javascript
16715var assert = require('assert');
16716
16717var R = require('../../../../dist/rambda.js');
16718var eq = require('./shared/eq');
16719describe('pipe', function() {
16720 it('performs left-to-right function composition', function() {
16721 // f :: (String, Number?) -> ([Number] -> [Number])
16722 var f = R.pipe(parseInt, R.multiply, R.map);
16723 eq(f.length, 2);
16724 eq(f('10')([1, 2, 3]), [10, 20, 30]);
16725 eq(f('10', 2)([1, 2, 3]), [2, 4, 6]);
16726 });
16727 it('passes context to functions', function() {
16728 function x(val) {
16729 return this.x * val;
16730 }
16731 function y(val) {
16732 return this.y * val;
16733 }
16734 function z(val) {
16735 return this.z * val;
16736 }
16737 var context = {
16738 a: R.pipe(x, y, z),
16739 x: 4,
16740 y: 2,
16741 z: 1
16742 };
16743 eq(context.a(5), 40);
16744 });
16745 it('can be applied to one argument', function() {
16746 var f = function(a, b, c) { return [a, b, c]; };
16747 var g = R.pipe(f);
16748 eq(g.length, 3);
16749 eq(g(1, 2, 3), [1, 2, 3]);
16750 });
16751});
16752```
16753
16754</details>
16755
16756[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pipe)
16757
16758### pluck
16759
16760```typescript
16761
16762pluck<K extends keyof T, T>(property: K, list: readonly T[]): Array<T[K]>
16763```
16764
16765It returns list of the values of `property` taken from the all objects inside `list`.
16766
16767```javascript
16768const list = [{a: 1}, {a: 2}, {b: 3}]
16769const property = 'a'
16770
16771R.pluck(list, property)
16772// => [1, 2]
16773```
16774
16775<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20list%20%3D%20%5B%7Ba%3A%201%7D%2C%20%7Ba%3A%202%7D%2C%20%7Bb%3A%203%7D%5D%0Aconst%20property%20%3D%20'a'%0A%0AR.pluck(list%2C%20property)%20%0A%2F%2F%20%3D%3E%20%5B1%2C%202%5D">Try this <strong>R.pluck</strong> example in Rambda REPL</a>
16776
16777<details>
16778
16779<summary>All Typescript definitions</summary>
16780
16781```typescript
16782pluck<K extends keyof T, T>(property: K, list: readonly T[]): Array<T[K]>;
16783pluck<T>(property: number, list: ReadonlyArray<{ [k: number]: T }>): T[];
16784pluck<P extends string>(property: P): <T>(list: ReadonlyArray<Record<P, T>>) => T[];
16785pluck(property: number): <T>(list: ReadonlyArray<{ [k: number]: T }>) => T[];
16786```
16787
16788</details>
16789
16790<details>
16791
16792<summary><strong>R.pluck</strong> source</summary>
16793
16794```javascript
16795import { map } from './map'
16796
16797export function pluck(property, list){
16798 if (arguments.length === 1) return _list => pluck(property, _list)
16799
16800 const willReturn = []
16801
16802 map(x => {
16803 if (x[ property ] !== undefined){
16804 willReturn.push(x[ property ])
16805 }
16806 }, list)
16807
16808 return willReturn
16809}
16810```
16811
16812</details>
16813
16814<details>
16815
16816<summary><strong>Tests</strong></summary>
16817
16818```javascript
16819import { pluck } from './pluck'
16820
16821test('happy', () => {
16822 expect(pluck('a')([ { a : 1 }, { a : 2 }, { b : 1 } ])).toEqual([ 1, 2 ])
16823})
16824
16825test('with number', () => {
16826 const input = [
16827 [ 1, 2 ],
16828 [ 3, 4 ],
16829 ]
16830
16831 expect(pluck(0, input)).toEqual([ 1, 3 ])
16832})
16833```
16834
16835</details>
16836
16837<details>
16838
16839<summary><strong>Typescript</strong> test</summary>
16840
16841```typescript
16842import {pluck} from 'rambda'
16843
16844describe('R.pluck', () => {
16845 it('with object', () => {
16846 interface ListMember {
16847 a: number,
16848 b: string,
16849 }
16850 const input: ListMember[] = [
16851 {a: 1, b: 'foo'},
16852 {a: 2, b: 'bar'},
16853 ]
16854 const resultA = pluck('a', input)
16855 const resultB = pluck('b')(input)
16856 resultA // $ExpectType number[]
16857 resultB // $ExpectType string[]
16858 })
16859
16860 it('with array', () => {
16861 const input = [
16862 [1, 2],
16863 [3, 4],
16864 [5, 6],
16865 ]
16866 const result = pluck(0, input)
16867 const resultCurry = pluck(0)(input)
16868 result // $ExpectType number[]
16869 resultCurry // $ExpectType number[]
16870 })
16871})
16872```
16873
16874</details>
16875
16876<details>
16877
16878<summary>1 failed <italic>Ramda.pluck</italic> specs
16879
16880> :boom: Reason for the failure: Ramda method behaves as a transducer
16881</summary>
16882
16883```javascript
16884var R = require('../../../../dist/rambda.js');
16885var eq = require('./shared/eq');
16886
16887describe('pluck', function() {
16888 var people = [
16889 {name: 'Fred', age: 23},
16890 {name: 'Wilma', age: 21},
16891 {name: 'Pebbles', age: 2}
16892 ];
16893 it('behaves as a transducer when given a transducer in list position', function() {
16894 var numbers = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
16895 var transducer = R.compose(R.pluck('a'), R.map(R.add(1)), R.take(2));
16896 eq(R.transduce(transducer, R.flip(R.append), [], numbers), [2, 3]);
16897 });
16898});
16899```
16900
16901</details>
16902
16903[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#pluck)
16904
16905### prepend
16906
16907```typescript
16908
16909prepend<T>(x: T, input: T[]): T[]
16910```
16911
16912It adds element `x` at the beginning of `list`.
16913
16914```javascript
16915const result = R.prepend('foo', ['bar', 'baz'])
16916// => ['foo', 'bar', 'baz']
16917```
16918
16919<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.prepend('foo'%2C%20%5B'bar'%2C%20'baz'%5D)%0A%2F%2F%20%3D%3E%20%5B'foo'%2C%20'bar'%2C%20'baz'%5D">Try this <strong>R.prepend</strong> example in Rambda REPL</a>
16920
16921<details>
16922
16923<summary>All Typescript definitions</summary>
16924
16925```typescript
16926prepend<T>(x: T, input: T[]): T[];
16927prepend<T>(x: T): (input: T[]) => T[];
16928```
16929
16930</details>
16931
16932<details>
16933
16934<summary><strong>R.prepend</strong> source</summary>
16935
16936```javascript
16937export function prepend(x, input){
16938 if (arguments.length === 1) return _input => prepend(x, _input)
16939
16940 if (typeof input === 'string') return [ x ].concat(input.split(''))
16941
16942 return [ x ].concat(input)
16943}
16944```
16945
16946</details>
16947
16948<details>
16949
16950<summary><strong>Tests</strong></summary>
16951
16952```javascript
16953import { prepend } from './prepend'
16954
16955test('happy', () => {
16956 expect(prepend('yes', [ 'foo', 'bar', 'baz' ])).toEqual([
16957 'yes',
16958 'foo',
16959 'bar',
16960 'baz',
16961 ])
16962})
16963
16964test('with empty list', () => {
16965 expect(prepend('foo')([])).toEqual([ 'foo' ])
16966})
16967
16968test('with string instead of array', () => {
16969 expect(prepend('foo')('bar')).toEqual([ 'foo', 'b', 'a', 'r' ])
16970})
16971```
16972
16973</details>
16974
16975<details>
16976
16977<summary><strong>Typescript</strong> test</summary>
16978
16979```typescript
16980import {prepend} from 'rambda'
16981
16982const list = [1, 2, 3]
16983
16984describe('R.prepend', () => {
16985 it('happy', () => {
16986 const result = prepend(4, list)
16987
16988 result // $ExpectType number[]
16989 })
16990 it('curried', () => {
16991 const result = prepend(4)(list)
16992
16993 result // $ExpectType number[]
16994 })
16995})
16996```
16997
16998</details>
16999
17000[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#prepend)
17001
17002### product
17003
17004```typescript
17005
17006product(list: readonly number[]): number
17007```
17008
17009```javascript
17010R.product([ 2, 3, 4 ])
17011// => 24)
17012```
17013
17014<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.product(%5B%202%2C%203%2C%204%20%5D)%0A%2F%2F%20%3D%3E%2024)">Try this <strong>R.product</strong> example in Rambda REPL</a>
17015
17016<details>
17017
17018<summary>All Typescript definitions</summary>
17019
17020```typescript
17021product(list: readonly number[]): number;
17022```
17023
17024</details>
17025
17026<details>
17027
17028<summary><strong>R.product</strong> source</summary>
17029
17030```javascript
17031import { multiply } from './multiply'
17032import { reduce } from './reduce'
17033
17034export const product = reduce(multiply, 1)
17035```
17036
17037</details>
17038
17039<details>
17040
17041<summary><strong>Tests</strong></summary>
17042
17043```javascript
17044import { product } from './product'
17045
17046test('happy', () => {
17047 expect(product([ 2, 3, 4 ])).toEqual(24)
17048})
17049
17050test('bad input', () => {
17051 expect(product([ null ])).toEqual(0)
17052 expect(product([])).toEqual(1)
17053})
17054```
17055
17056</details>
17057
17058<details>
17059
17060<summary><strong>Typescript</strong> test</summary>
17061
17062```typescript
17063import {product} from 'rambda'
17064
17065describe('R.product', () => {
17066 it('happy', () => {
17067 const result = product([1, 2, 3])
17068
17069 result // $ExpectType number
17070 })
17071})
17072```
17073
17074</details>
17075
17076[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#product)
17077
17078### prop
17079
17080```typescript
17081
17082prop<P extends keyof T, T>(propToFind: P, obj: T): T[P]
17083```
17084
17085It returns the value of property `propToFind` in `obj`.
17086
17087If there is no such property, it returns `undefined`.
17088
17089```javascript
17090const result = [
17091 R.prop('x', {x: 100}),
17092 R.prop('x', {a: 1})
17093]
17094// => [100, undefined]
17095```
17096
17097<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.prop('x'%2C%20%7Bx%3A%20100%7D)%2C%20%0A%20%20R.prop('x'%2C%20%7Ba%3A%201%7D)%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B100%2C%20undefined%5D">Try this <strong>R.prop</strong> example in Rambda REPL</a>
17098
17099<details>
17100
17101<summary>All Typescript definitions</summary>
17102
17103```typescript
17104prop<P extends keyof T, T>(propToFind: P, obj: T): T[P];
17105prop<P extends string>(p: P): <T>(propToFind: Record<P, T>) => T;
17106prop<P extends string, T>(p: P): (propToFind: Record<P, T>) => T;
17107```
17108
17109</details>
17110
17111<details>
17112
17113<summary><strong>R.prop</strong> source</summary>
17114
17115```javascript
17116export function prop(propToFind, obj){
17117 if (arguments.length === 1) return _obj => prop(propToFind, _obj)
17118
17119 if (!obj) return undefined
17120
17121 return obj[ propToFind ]
17122}
17123```
17124
17125</details>
17126
17127<details>
17128
17129<summary><strong>Tests</strong></summary>
17130
17131```javascript
17132import { prop } from './prop'
17133
17134test('prop', () => {
17135 expect(prop('foo')({ foo : 'baz' })).toEqual('baz')
17136
17137 expect(prop('bar')({ foo : 'baz' })).toEqual(undefined)
17138
17139 expect(prop('bar')(null)).toEqual(undefined)
17140})
17141```
17142
17143</details>
17144
17145<details>
17146
17147<summary><strong>Typescript</strong> test</summary>
17148
17149```typescript
17150import {prop} from 'rambda'
17151
17152const obj = {a: 1, b: 'foo'}
17153
17154describe('R.prop', () => {
17155 it('happy', () => {
17156 const result = prop('a', obj)
17157
17158 result // $ExpectType number
17159 })
17160 it('curried', () => {
17161 const result = prop('b')(obj)
17162
17163 result // $ExpectType string
17164 })
17165})
17166```
17167
17168</details>
17169
17170[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#prop)
17171
17172### propEq
17173
17174```typescript
17175
17176propEq<T, K extends keyof T>(propToFind: K, valueToMatch: T[K], obj: T): boolean
17177```
17178
17179It returns true if `obj` has property `propToFind` and its value is equal to `valueToMatch`.
17180
17181```javascript
17182const obj = { foo: 'bar' }
17183const secondObj = { foo: 1 }
17184
17185const propToFind = 'foo'
17186const valueToMatch = 'bar'
17187
17188const result = [
17189 R.propEq(propToFind, valueToMatch, obj),
17190 R.propEq(propToFind, valueToMatch, secondObj)
17191]
17192// => [true, false]
17193```
17194
17195<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7B%20foo%3A%20'bar'%20%7D%0Aconst%20secondObj%20%3D%20%7B%20foo%3A%201%20%7D%0A%0Aconst%20propToFind%20%3D%20'foo'%0Aconst%20valueToMatch%20%3D%20'bar'%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.propEq(propToFind%2C%20valueToMatch%2C%20obj)%2C%0A%20%20R.propEq(propToFind%2C%20valueToMatch%2C%20secondObj)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.propEq</strong> example in Rambda REPL</a>
17196
17197<details>
17198
17199<summary>All Typescript definitions</summary>
17200
17201```typescript
17202propEq<T, K extends keyof T>(propToFind: K, valueToMatch: T[K], obj: T): boolean;
17203propEq<T, K extends keyof T>(propToFind: K, valueToMatch: T[K]): (obj: T) => boolean;
17204propEq<T, K extends keyof T>(propToFind: K): {
17205 (valueToMatch: T[K], obj: T): boolean;
17206 (valueToMatch: T[K]): (obj: T) => boolean;
17207};
17208```
17209
17210</details>
17211
17212<details>
17213
17214<summary><strong>R.propEq</strong> source</summary>
17215
17216```javascript
17217import { curry } from './curry'
17218
17219function propEqFn(
17220 propToFind, valueToMatch, obj
17221){
17222 if (!obj) return false
17223
17224 return obj[ propToFind ] === valueToMatch
17225}
17226
17227export const propEq = curry(propEqFn)
17228```
17229
17230</details>
17231
17232<details>
17233
17234<summary><strong>Tests</strong></summary>
17235
17236```javascript
17237import { propEq } from './propEq'
17238
17239test('happy', () => {
17240 expect(propEq('foo', 'bar')({ foo : 'bar' })).toBeTrue()
17241 expect(propEq('foo', 'bar')({ foo : 'baz' })).toBeFalse()
17242 expect(propEq('foo')('bar')({ foo : 'baz' })).toBeFalse()
17243 expect(propEq(
17244 'foo', 'bar', null
17245 )).toBeFalse()
17246})
17247```
17248
17249</details>
17250
17251<details>
17252
17253<summary><strong>Typescript</strong> test</summary>
17254
17255```typescript
17256import {propEq} from 'rambda'
17257
17258const property = 'foo'
17259const numberProperty = 1
17260const value = 'bar'
17261const obj = {[property]: value}
17262const objWithNumberIndex = {[numberProperty]: value}
17263
17264describe('R.propEq', () => {
17265 it('happy', () => {
17266 const result = propEq(property, value, obj)
17267 result // $ExpectType boolean
17268 })
17269 it('number is property', () => {
17270 const result = propEq(1, value, objWithNumberIndex)
17271 result // $ExpectType boolean
17272 })
17273 it('with optional property', () => {
17274 interface MyType {
17275 optional?: string | number,
17276 }
17277
17278 const myObject: MyType = {}
17279 const valueToFind = '1111'
17280 const optionalValueToFind: string | number | undefined = '1111'
17281 const result = propEq('optional', valueToFind, myObject)
17282 const result2 = propEq('optional', optionalValueToFind, myObject)
17283 result // $ExpectType boolean
17284 result2 // $ExpectType boolean
17285 })
17286})
17287```
17288
17289</details>
17290
17291<details>
17292
17293<summary>1 failed <italic>Ramda.propEq</italic> specs
17294
17295> :boom: Reason for the failure: Ramda method pass to `equals` method if available
17296</summary>
17297
17298```javascript
17299var R = require('../../../../dist/rambda.js');
17300var eq = require('./shared/eq');
17301
17302describe('propEq', function() {
17303 var obj1 = {name: 'Abby', age: 7, hair: 'blond'};
17304 var obj2 = {name: 'Fred', age: 12, hair: 'brown'};
17305 it('handles number as property', function() {
17306 var deities = ['Cthulhu', 'Dagon', 'Yog-Sothoth'];
17307 eq(R.propEq(0, 'Cthulhu', deities), true);
17308 eq(R.propEq(1, 'Dagon', deities), true);
17309 eq(R.propEq(2, 'Yog-Sothoth', deities), true);
17310 eq(R.propEq(-1, 'Yog-Sothoth', deities), true);
17311 eq(R.propEq(3, undefined, deities), true);
17312 });
17313 it('has R.equals semantics', function() {
17314 function Just(x) { this.value = x; }
17315 Just.prototype.equals = function(x) {
17316 return x instanceof Just && R.equals(x.value, this.value);
17317 };
17318 eq(R.propEq('value', 0, {value: -0}), false);
17319 eq(R.propEq('value', -0, {value: 0}), false);
17320 eq(R.propEq('value', NaN, {value: NaN}), true);
17321 eq(R.propEq('value', new Just([42]), {value: new Just([42])}), true);
17322 });
17323});
17324```
17325
17326</details>
17327
17328[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#propEq)
17329
17330### propIs
17331
17332```typescript
17333
17334propIs(type: any, name: string, obj: any): boolean
17335```
17336
17337It returns `true` if `property` of `obj` is from `target` type.
17338
17339```javascript
17340const obj = {a:1, b: 'foo'}
17341const property = 'foo'
17342
17343const result = [
17344 R.propIs(String, property, obj),
17345 R.propIs(Number, property, obj)
17346]
17347// => [true, false]
17348```
17349
17350<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7Ba%3A1%2C%20b%3A%20'foo'%7D%0Aconst%20property%20%3D%20'foo'%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.propIs(String%2C%20property%2C%20obj)%2C%0A%20%20R.propIs(Number%2C%20property%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.propIs</strong> example in Rambda REPL</a>
17351
17352<details>
17353
17354<summary>All Typescript definitions</summary>
17355
17356```typescript
17357propIs(type: any, name: string, obj: any): boolean;
17358propIs(type: any, name: string): (obj: any) => boolean;
17359propIs(type: any): {
17360 (name: string, obj: any): boolean;
17361 (name: string): (obj: any) => boolean;
17362};
17363```
17364
17365</details>
17366
17367<details>
17368
17369<summary><strong>R.propIs</strong> source</summary>
17370
17371```javascript
17372import { curry } from './curry'
17373import { is } from './is'
17374
17375function propIsFn(
17376 targetPrototype, property, obj
17377){
17378 return is(targetPrototype, obj[ property ])
17379}
17380
17381export const propIs = curry(propIsFn)
17382```
17383
17384</details>
17385
17386<details>
17387
17388<summary><strong>Tests</strong></summary>
17389
17390```javascript
17391import { propIs } from './propIs'
17392
17393const obj = { value : 1 }
17394const property = 'value'
17395
17396test('when true', () => {
17397 expect(propIs(
17398 Number, property, obj
17399 )).toBeTrue()
17400})
17401
17402test('when false', () => {
17403 expect(propIs(
17404 String, property, obj
17405 )).toBeFalse()
17406 expect(propIs(
17407 String, property, {}
17408 )).toBeFalse()
17409})
17410```
17411
17412</details>
17413
17414<details>
17415
17416<summary><strong>Typescript</strong> test</summary>
17417
17418```typescript
17419import {propIs} from 'rambda'
17420
17421const property = 'a'
17422const obj = {a: 1}
17423
17424describe('R.propIs', () => {
17425 it('happy', () => {
17426 const result = propIs(Number, property, obj)
17427 result // $ExpectType boolean
17428 })
17429
17430 it('curried', () => {
17431 const result = propIs(Number, property)(obj)
17432 result // $ExpectType boolean
17433 })
17434})
17435```
17436
17437</details>
17438
17439[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#propIs)
17440
17441### propOr
17442
17443```typescript
17444
17445propOr<T>(defaultValue: T, property: string, obj: { [key: string]: T}): T
17446```
17447
17448It returns either `defaultValue` or the value of `property` in `obj`.
17449
17450```javascript
17451const obj = {a: 1}
17452const defaultValue = 'DEFAULT_VALUE'
17453const property = 'a'
17454
17455const result = [
17456 R.propOr(defaultValue, property, obj),
17457 R.propOr(defaultValue, 'foo', obj)
17458]
17459// => [1, 'DEFAULT_VALUE']
17460```
17461
17462<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20obj%20%3D%20%7Ba%3A%201%7D%0Aconst%20defaultValue%20%3D%20'DEFAULT_VALUE'%0Aconst%20property%20%3D%20'a'%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.propOr(defaultValue%2C%20property%2C%20obj)%2C%0A%20%20R.propOr(defaultValue%2C%20'foo'%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5B1%2C%20'DEFAULT_VALUE'%5D">Try this <strong>R.propOr</strong> example in Rambda REPL</a>
17463
17464<details>
17465
17466<summary>All Typescript definitions</summary>
17467
17468```typescript
17469propOr<T>(defaultValue: T, property: string, obj: { [key: string]: T}): T;
17470propOr<T>(defaultValue: T, property: string): (obj: { [key: string]: T}) => T;
17471propOr<T>(defaultValue: T): FunctionToolbelt.Curry<(property: string, obj: { [key: string]: T}) => T>;
17472```
17473
17474</details>
17475
17476<details>
17477
17478<summary><strong>R.propOr</strong> source</summary>
17479
17480```javascript
17481import { curry } from './curry'
17482import { defaultTo } from './defaultTo'
17483
17484function propOrFn(
17485 defaultValue, property, obj
17486){
17487 if (!obj) return defaultValue
17488
17489 return defaultTo(defaultValue, obj[ property ])
17490}
17491
17492export const propOr = curry(propOrFn)
17493```
17494
17495</details>
17496
17497<details>
17498
17499<summary><strong>Tests</strong></summary>
17500
17501```javascript
17502import { propOr } from './propOr'
17503
17504test('propOr (result)', () => {
17505 const obj = { a : 1 }
17506 expect(propOr(
17507 'default', 'a', obj
17508 )).toEqual(1)
17509 expect(propOr(
17510 'default', 'notExist', obj
17511 )).toEqual('default')
17512 expect(propOr(
17513 'default', 'notExist', null
17514 )).toEqual('default')
17515})
17516
17517test('propOr (currying)', () => {
17518 const obj = { a : 1 }
17519 expect(propOr('default')('a', obj)).toEqual(1)
17520 expect(propOr('default', 'a')(obj)).toEqual(1)
17521 expect(propOr('default')('notExist', obj)).toEqual('default')
17522 expect(propOr('default', 'notExist')(obj)).toEqual('default')
17523})
17524```
17525
17526</details>
17527
17528<details>
17529
17530<summary><strong>Typescript</strong> test</summary>
17531
17532```typescript
17533import {propOr} from 'rambda'
17534
17535const obj = {foo: 'bar'}
17536const property = 'foo'
17537const fallback = 'fallback'
17538
17539describe('R.propOr', () => {
17540 it('happy', () => {
17541 const result = propOr(fallback, property, obj)
17542 result // $ExpectType string
17543 })
17544 it('curry 1', () => {
17545 const result = propOr(fallback)(property, obj)
17546 result // $ExpectType string
17547 })
17548 it('curry 2', () => {
17549 const result = propOr(fallback, property)(obj)
17550 result // $ExpectType string
17551 })
17552 it('curry 3', () => {
17553 const result = propOr(fallback)(property)(obj)
17554 result // $ExpectType string
17555 })
17556})
17557```
17558
17559</details>
17560
17561[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#propOr)
17562
17563### props
17564
17565```typescript
17566
17567props<P extends string, T>(propsToPick: P[], obj: Record<P, T>): T[]
17568```
17569
17570It takes list with properties `propsToPick` and returns a list with property values in `obj`.
17571
17572```javascript
17573const result = [
17574 R.props(['a', 'b'], {a:1, c:3})
17575// => [1, undefined]
17576```
17577
17578<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.props(%5B'a'%2C%20'b'%5D%2C%20%7Ba%3A1%2C%20c%3A3%7D)%0A%2F%2F%20%3D%3E%20%5B1%2C%20undefined%5D">Try this <strong>R.props</strong> example in Rambda REPL</a>
17579
17580<details>
17581
17582<summary>All Typescript definitions</summary>
17583
17584```typescript
17585props<P extends string, T>(propsToPick: P[], obj: Record<P, T>): T[];
17586props<P extends string>(propsToPick: P[]): <T>(obj: Record<P, T>) => T[];
17587props<P extends string, T>(propsToPick: P[]): (obj: Record<P, T>) => T[];
17588```
17589
17590</details>
17591
17592<details>
17593
17594<summary><strong>R.props</strong> source</summary>
17595
17596```javascript
17597import { _isArray } from './_internals/_isArray'
17598import { mapArray } from './map'
17599
17600export function props(propsToPick, obj){
17601 if (arguments.length === 1){
17602 return _obj => props(propsToPick, _obj)
17603 }
17604 if (!_isArray(propsToPick)){
17605 throw new Error('propsToPick is not a list')
17606 }
17607
17608 return mapArray(prop => obj[ prop ], propsToPick)
17609}
17610```
17611
17612</details>
17613
17614<details>
17615
17616<summary><strong>Tests</strong></summary>
17617
17618```javascript
17619import { props } from './props'
17620
17621const obj = {
17622 a : 1,
17623 b : 2,
17624}
17625const propsToPick = [ 'a', 'c' ]
17626
17627test('happy', () => {
17628 const result = props(propsToPick, obj)
17629 expect(result).toEqual([ 1, undefined ])
17630})
17631
17632test('curried', () => {
17633 const result = props(propsToPick)(obj)
17634 expect(result).toEqual([ 1, undefined ])
17635})
17636```
17637
17638</details>
17639
17640<details>
17641
17642<summary><strong>Typescript</strong> test</summary>
17643
17644```typescript
17645import {props} from 'rambda'
17646
17647const obj = {a: 1, b: 2}
17648
17649describe('R.props', () => {
17650 it('happy', () => {
17651 const result = props(['a', 'b'], obj)
17652
17653 result // $ExpectType number[]
17654 })
17655 it('curried', () => {
17656 const result = props(['a', 'b'])(obj)
17657
17658 result // $ExpectType number[]
17659 })
17660})
17661```
17662
17663</details>
17664
17665[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#props)
17666
17667### range
17668
17669```typescript
17670
17671range(startInclusive: number, endExclusive: number): number[]
17672```
17673
17674It returns list of numbers between `startInclusive` to `endExclusive` markers.
17675
17676```javascript
17677R.range(0, 5)
17678// => [0, 1, 2, 3, 4]
17679```
17680
17681<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.range(0%2C%205)%0A%2F%2F%20%3D%3E%20%5B0%2C%201%2C%202%2C%203%2C%204%5D">Try this <strong>R.range</strong> example in Rambda REPL</a>
17682
17683<details>
17684
17685<summary>All Typescript definitions</summary>
17686
17687```typescript
17688range(startInclusive: number, endExclusive: number): number[];
17689range(startInclusive: number): (endExclusive: number) => number[];
17690```
17691
17692</details>
17693
17694<details>
17695
17696<summary><strong>R.range</strong> source</summary>
17697
17698```javascript
17699export function range(start, end){
17700 if (arguments.length === 1) return _end => range(start, _end)
17701
17702 if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){
17703 throw new TypeError('Both arguments to range must be numbers')
17704 }
17705
17706 if (end < start) return []
17707
17708 const len = end - start
17709 const willReturn = Array(len)
17710
17711 for (let i = 0; i < len; i++){
17712 willReturn[ i ] = start + i
17713 }
17714
17715 return willReturn
17716}
17717```
17718
17719</details>
17720
17721<details>
17722
17723<summary><strong>Tests</strong></summary>
17724
17725```javascript
17726import { range } from './range'
17727
17728test('happy', () => {
17729 expect(range(0, 10)).toEqual([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ])
17730})
17731
17732test('end range is bigger than start range', () => {
17733 expect(range(7, 3)).toEqual([])
17734 expect(range(5, 5)).toEqual([])
17735})
17736
17737test('with bad input', () => {
17738 const throwMessage = 'Both arguments to range must be numbers'
17739 expect(() => range('a', 6)).toThrowWithMessage(Error, throwMessage)
17740 expect(() => range(6, 'z')).toThrowWithMessage(Error, throwMessage)
17741})
17742
17743test('curry', () => {
17744 expect(range(0)(10)).toEqual([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ])
17745})
17746```
17747
17748</details>
17749
17750<details>
17751
17752<summary><strong>Typescript</strong> test</summary>
17753
17754```typescript
17755import {range} from 'rambda'
17756
17757describe('R.range', () => {
17758 it('happy', () => {
17759 const result = range(1, 4)
17760
17761 result // $ExpectType number[]
17762 })
17763 it('curried', () => {
17764 const result = range(1)(4)
17765
17766 result // $ExpectType number[]
17767 })
17768})
17769```
17770
17771</details>
17772
17773[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#range)
17774
17775### reduce
17776
17777```typescript
17778
17779reduce<T, TResult>(reducer: (prev: TResult, current: T, i: number) => TResult, initialValue: TResult, list: readonly T[]): TResult
17780```
17781
17782> :boom: It passes index of the list as third argument to `reducer` function.
17783
17784```javascript
17785const list = [1, 2, 3]
17786const initialValue = 10
17787const reducer = (prev, current) => prev * current
17788
17789const result = R.reduce(reducer, initialValue, list)
17790// => 60
17791```
17792
17793<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20initialValue%20%3D%2010%0Aconst%20reducer%20%3D%20(prev%2C%20current)%20%3D%3E%20prev%20*%20current%0A%0Aconst%20result%20%3D%20R.reduce(reducer%2C%20initialValue%2C%20list)%0A%2F%2F%20%3D%3E%2060">Try this <strong>R.reduce</strong> example in Rambda REPL</a>
17794
17795<details>
17796
17797<summary>All Typescript definitions</summary>
17798
17799```typescript
17800reduce<T, TResult>(reducer: (prev: TResult, current: T, i: number) => TResult, initialValue: TResult, list: readonly T[]): TResult;
17801reduce<T, TResult>(reducer: (prev: TResult, current: T) => TResult, initialValue: TResult, list: readonly T[]): TResult;
17802reduce<T, TResult>(reducer: (prev: TResult, current: T, i?: number) => TResult): (initialValue: TResult, list: readonly T[]) => TResult;
17803reduce<T, TResult>(reducer: (prev: TResult, current: T, i?: number) => TResult, initialValue: TResult): (list: readonly T[]) => TResult;
17804```
17805
17806</details>
17807
17808<details>
17809
17810<summary><strong>R.reduce</strong> source</summary>
17811
17812```javascript
17813import { _isArray } from './_internals/_isArray'
17814import { _keys } from './_internals/_keys'
17815import { curry } from './curry'
17816
17817function reduceFn(
17818 reducer, acc, list
17819){
17820 if (!_isArray(list)){
17821 throw new TypeError('reduce: list must be array or iterable')
17822 }
17823 let index = 0
17824 const len = list.length
17825
17826 while (index < len){
17827 acc = reducer(
17828 acc, list[ index ], index, list
17829 )
17830 index++
17831 }
17832
17833 return acc
17834}
17835
17836export const reduce = curry(reduceFn)
17837```
17838
17839</details>
17840
17841<details>
17842
17843<summary><strong>Tests</strong></summary>
17844
17845```javascript
17846import { reduce } from './reduce'
17847
17848const reducer = (
17849 prev, current, i
17850) => {
17851 expect(i).toBeNumber()
17852
17853 return prev + current
17854}
17855const initialValue = 1
17856const list = [ 1, 2, 3 ]
17857
17858test('happy', () => {
17859 expect(reduce(
17860 reducer, initialValue, list
17861 )).toEqual(7)
17862})
17863
17864test('with object as iterable', () => {
17865 expect(() =>
17866 reduce(
17867 reducer, initialValue, {
17868 a : 1,
17869 b : 2,
17870 }
17871 )).toThrowWithMessage(TypeError, 'reduce: list must be array or iterable')
17872})
17873
17874test('with undefined as iterable', () => {
17875 expect(() => reduce(
17876 reducer, initialValue, undefined
17877 )).toThrowWithMessage(TypeError,
17878 'reduce: list must be array or iterable')
17879})
17880```
17881
17882</details>
17883
17884<details>
17885
17886<summary><strong>Typescript</strong> test</summary>
17887
17888```typescript
17889import {reduce} from 'rambda'
17890
17891describe('R.reduce', () => {
17892 it('happy', () => {
17893 const result = reduce<number, number>(
17894 (acc, elem) => {
17895 acc // $ExpectType number
17896 elem // $ExpectType number
17897 return acc + elem
17898 },
17899 1,
17900 [1, 2, 3]
17901 )
17902
17903 result // $ExpectType number
17904 })
17905
17906 it('with two types', () => {
17907 const result = reduce<number, string>(
17908 (acc, elem) => {
17909 acc // $ExpectType string
17910 elem // $ExpectType number
17911
17912 return `${acc}${elem}`
17913 },
17914 'foo',
17915 [1, 2, 3]
17916 )
17917
17918 result // $ExpectType string
17919 })
17920
17921 it('with index', () => {
17922 const result = reduce<number, number>(
17923 (acc, elem, i) => {
17924 acc // $ExpectType number
17925 elem // $ExpectType number
17926 i // $ExpectType number
17927 return acc + elem
17928 },
17929 1,
17930 [1, 2, 3]
17931 )
17932
17933 result // $ExpectType number
17934 })
17935
17936 it('fallback', () => {
17937 const result = reduce(
17938 (acc, val) => {
17939 acc // $ExpectType number
17940 return acc + val
17941 },
17942 1,
17943 [1, 2, 3]
17944 )
17945
17946 result // $ExpectType number
17947 })
17948
17949 it('fallback with index', () => {
17950 const result = reduce(
17951 (acc, val, i) => {
17952 acc // $ExpectType number
17953 i // $ExpectType number
17954 return acc + val
17955 },
17956 1,
17957 [1, 2, 3]
17958 )
17959
17960 result // $ExpectType number
17961 })
17962
17963 it('fallback with two types', () => {
17964 const result = reduce(
17965 (acc, val) => {
17966 acc // $ExpectType string
17967 return acc + val
17968 },
17969 'foo',
17970 [1, 2, 3]
17971 )
17972
17973 result // $ExpectType string
17974 })
17975})
17976```
17977
17978</details>
17979
17980<details>
17981
17982<summary>2 failed <italic>Ramda.reduce</italic> specs
17983
17984> :boom: Reason for the failure: Rambda library doesn't have `R.reduced` method | Ramda method pass to `reduce` method
17985</summary>
17986
17987```javascript
17988var R = require('../../../../dist/rambda.js');
17989var eq = require('./shared/eq');
17990
17991describe('reduce', function() {
17992 var add = function(a, b) {return a + b;};
17993 var mult = function(a, b) {return a * b;};
17994 it('Prefers the use of the iterator of an object over reduce (and handles short-circuits)', function() {
17995 var symIterator = (typeof Symbol !== 'undefined') ? Symbol.iterator : '@@iterator';
17996 function Reducible(arr) {
17997 this.arr = arr;
17998 }
17999 Reducible.prototype.reduce = function(f, init) {
18000 var acc = init;
18001 for (var i = 0; i < this.arr.length; i += 1) {
18002 acc = f(acc, this.arr[i]);
18003 }
18004 return acc;
18005 };
18006 Reducible.prototype[symIterator] = function() {
18007 var a = this.arr;
18008 return {
18009 _pos: 0,
18010 next: function() {
18011 if (this._pos < a.length) {
18012 var v = a[this._pos];
18013 this._pos += 1;
18014 return {
18015 value: v,
18016 done: false
18017 };
18018 } else {
18019 return {
18020 done: true
18021 };
18022 }
18023 }
18024 };
18025 };
18026 var xf = R.take(2);
18027 var apendingT = { };
18028 apendingT['@@transducer/result'] = R.identity;
18029 apendingT['@@transducer/step'] = R.flip(R.append);
18030 var rfn = xf(apendingT);
18031 var list = new Reducible([1, 2, 3, 4, 5, 6]);
18032 eq(R.reduce(rfn, [], list), [1, 2]);
18033 });
18034 it('short circuits with reduced', function() {
18035 var addWithMaxOf10 = function(acc, val) {return acc + val > 10 ? R.reduced(acc) : acc + val;};
18036 eq(R.reduce(addWithMaxOf10, 0, [1, 2, 3, 4]), 10);
18037 eq(R.reduce(addWithMaxOf10, 0, [2, 4, 6, 8]), 6);
18038 });
18039});
18040```
18041
18042</details>
18043
18044[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#reduce)
18045
18046### reject
18047
18048```typescript
18049
18050reject<T>(predicate: FilterFunctionArray<T>, list: readonly T[]): T[]
18051```
18052
18053It has the opposite effect of `R.filter`.
18054
18055```javascript
18056const list = [1, 2, 3, 4]
18057const obj = {a: 1, b: 2}
18058const predicate = x => x > 1
18059
18060const result = [
18061 R.reject(predicate, list)
18062 R.reject(predicate, obj)
18063]
18064// => [[1, 2], {a: 1}]
18065```
18066
18067<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%5D%0Aconst%20obj%20%3D%20%7Ba%3A%201%2C%20b%3A%202%7D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%201%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.reject(predicate%2C%20list)%0A%20%20R.reject(predicate%2C%20obj)%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%202%5D%2C%20%7Ba%3A%201%7D%5D">Try this <strong>R.reject</strong> example in Rambda REPL</a>
18068
18069<details>
18070
18071<summary>All Typescript definitions</summary>
18072
18073```typescript
18074reject<T>(predicate: FilterFunctionArray<T>, list: readonly T[]): T[];
18075reject<T>(predicate: FilterFunctionArray<T>): (list: readonly T[]) => T[];
18076reject<T>(predicate: FilterFunctionArray<T>, obj: Dictionary<T>): Dictionary<T>;
18077reject<T, U>(predicate: FilterFunctionArray<T>): (obj: Dictionary<T>) => Dictionary<T>;
18078```
18079
18080</details>
18081
18082<details>
18083
18084<summary><strong>R.reject</strong> source</summary>
18085
18086```javascript
18087import { filter } from './filter'
18088
18089export function reject(predicate, list){
18090 if (arguments.length === 1) return _list => reject(predicate, _list)
18091
18092 return filter(x => !predicate(x), list)
18093}
18094```
18095
18096</details>
18097
18098<details>
18099
18100<summary><strong>Tests</strong></summary>
18101
18102```javascript
18103import { reject } from './reject'
18104
18105const isOdd = n => n % 2 === 1
18106
18107test('with array', () => {
18108 expect(reject(isOdd)([ 1, 2, 3, 4 ])).toEqual([ 2, 4 ])
18109})
18110
18111test('with object', () => {
18112 const obj = {
18113 a : 1,
18114 b : 2,
18115 c : 3,
18116 d : 4,
18117 }
18118 expect(reject(isOdd, obj)).toEqual({
18119 b : 2,
18120 d : 4,
18121 })
18122})
18123```
18124
18125</details>
18126
18127<details>
18128
18129<summary><strong>Typescript</strong> test</summary>
18130
18131```typescript
18132import {reject} from 'rambda'
18133
18134describe('R.reject with array', () => {
18135 it('happy', () => {
18136 const result = reject(
18137 x => {
18138 x // $ExpectType number
18139 return x > 1
18140 },
18141 [1, 2, 3]
18142 )
18143 result // $ExpectType number[]
18144 })
18145 it('curried require explicit type', () => {
18146 const result = reject<number>(x => {
18147 x // $ExpectType number
18148 return x > 1
18149 })([1, 2, 3])
18150 result // $ExpectType number[]
18151 })
18152})
18153
18154describe('R.reject with objects', () => {
18155 it('happy', () => {
18156 const result = reject(
18157 x => {
18158 x // $ExpectType number
18159
18160 return x > 1
18161 },
18162 {a: 1, b: 2}
18163 )
18164 result // $ExpectType Dictionary<number>
18165 })
18166 it('curried require dummy type', () => {
18167 const result = reject<number, any>(x => {
18168 return x > 1
18169 })({a: 1, b: 2})
18170 result // $ExpectType Dictionary<number>
18171 })
18172})
18173```
18174
18175</details>
18176
18177<details>
18178
18179<summary>1 failed <italic>Ramda.reject</italic> specs
18180
18181> :boom: Reason for the failure: Ramda method dispatches to `filter` method
18182</summary>
18183
18184```javascript
18185var R = require('../../../../dist/rambda.js');
18186var eq = require('./shared/eq');
18187
18188describe('reject', function() {
18189 var even = function(x) {return x % 2 === 0;};
18190 it('dispatches to `filter` method', function() {
18191 function Nothing() {}
18192 Nothing.value = new Nothing();
18193 Nothing.prototype.filter = function() {
18194 return this;
18195 };
18196 function Just(x) { this.value = x; }
18197 Just.prototype.filter = function(pred) {
18198 return pred(this.value) ? this : Nothing.value;
18199 };
18200 var m = new Just(42);
18201 eq(R.filter(R.T, m), m);
18202 eq(R.filter(R.F, m), Nothing.value);
18203 eq(R.reject(R.T, m), Nothing.value);
18204 eq(R.reject(R.F, m), m);
18205 });
18206});
18207```
18208
18209</details>
18210
18211[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#reject)
18212
18213### repeat
18214
18215```typescript
18216
18217repeat<T>(x: T): (timesToRepeat: number) => T[]
18218```
18219
18220```javascript
18221R.repeat('foo', 3)
18222// => ['foo', 'foo', 'foo']
18223```
18224
18225<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.repeat('foo'%2C%203)%0A%2F%2F%20%3D%3E%20%5B'foo'%2C%20'foo'%2C%20'foo'%5D">Try this <strong>R.repeat</strong> example in Rambda REPL</a>
18226
18227<details>
18228
18229<summary>All Typescript definitions</summary>
18230
18231```typescript
18232repeat<T>(x: T): (timesToRepeat: number) => T[];
18233repeat<T>(x: T, timesToRepeat: number): T[];
18234```
18235
18236</details>
18237
18238<details>
18239
18240<summary><strong>R.repeat</strong> source</summary>
18241
18242```javascript
18243export function repeat(x, timesToRepeat){
18244 if (arguments.length === 1){
18245 return _timesToRepeat => repeat(x, _timesToRepeat)
18246 }
18247
18248 return Array(timesToRepeat).fill(x)
18249}
18250```
18251
18252</details>
18253
18254<details>
18255
18256<summary><strong>Tests</strong></summary>
18257
18258```javascript
18259import { repeat } from './repeat'
18260
18261test('repeat', () => {
18262 expect(repeat('')(3)).toEqual([ '', '', '' ])
18263 expect(repeat('foo', 3)).toEqual([ 'foo', 'foo', 'foo' ])
18264
18265 const obj = {}
18266 const arr = repeat(obj, 3)
18267
18268 expect(arr).toEqual([ {}, {}, {} ])
18269
18270 expect(arr[ 0 ] === arr[ 1 ]).toBeTrue()
18271})
18272```
18273
18274</details>
18275
18276<details>
18277
18278<summary><strong>Typescript</strong> test</summary>
18279
18280```typescript
18281import {repeat} from 'rambda'
18282
18283describe('R.repeat', () => {
18284 it('happy', () => {
18285 const result = repeat(4, 7)
18286
18287 result // $ExpectType number[]
18288 })
18289 it('curried', () => {
18290 const result = repeat(4)(7)
18291
18292 result // $ExpectType number[]
18293 })
18294})
18295```
18296
18297</details>
18298
18299[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#repeat)
18300
18301### replace
18302
18303```typescript
18304
18305replace(strOrRegex: RegExp | string, replacer: string, str: string): string
18306```
18307
18308It replaces `strOrRegex` found in `str` with `replacer`.
18309
18310```javascript
18311const strOrRegex = /o/g
18312
18313const result = R.replace(strOrRegex, '|0|', 'foo')
18314// => 'f|0||0|'
18315```
18316
18317<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20strOrRegex%20%3D%20%2Fo%2Fg%0A%0Aconst%20result%20%3D%20R.replace(strOrRegex%2C%20'%7C0%7C'%2C%20'foo')%0A%2F%2F%20%3D%3E%20'f%7C0%7C%7C0%7C'">Try this <strong>R.replace</strong> example in Rambda REPL</a>
18318
18319<details>
18320
18321<summary>All Typescript definitions</summary>
18322
18323```typescript
18324replace(strOrRegex: RegExp | string, replacer: string, str: string): string;
18325replace(strOrRegex: RegExp | string, replacer: string): (str: string) => string;
18326replace(strOrRegex: RegExp | string): (replacer: string) => (str: string) => string;
18327```
18328
18329</details>
18330
18331<details>
18332
18333<summary><strong>R.replace</strong> source</summary>
18334
18335```javascript
18336import { curry } from './curry'
18337
18338function replaceFn(
18339 pattern, replacer, str
18340){
18341 return str.replace(pattern, replacer)
18342}
18343
18344export const replace = curry(replaceFn)
18345```
18346
18347</details>
18348
18349<details>
18350
18351<summary><strong>Tests</strong></summary>
18352
18353```javascript
18354import { replace } from './replace'
18355
18356test('happy', () => {
18357 expect(replace(
18358 'foo', 'yes', 'foo bar baz'
18359 )).toEqual('yes bar baz')
18360})
18361
18362test('1', () => {
18363 expect(replace(/\s/g)('|')('foo bar baz')).toEqual('foo|bar|baz')
18364})
18365
18366test('2', () => {
18367 expect(replace(/\s/g)('|', 'foo bar baz')).toEqual('foo|bar|baz')
18368})
18369
18370test('3', () => {
18371 expect(replace(/\s/g, '|')('foo bar baz')).toEqual('foo|bar|baz')
18372})
18373```
18374
18375</details>
18376
18377<details>
18378
18379<summary><strong>Typescript</strong> test</summary>
18380
18381```typescript
18382import {replace} from 'rambda'
18383
18384const str = 'foo bar foo'
18385const replacer = 'bar'
18386
18387describe('R.replace', () => {
18388 it('happy', () => {
18389 const result = replace(/foo/g, replacer, str)
18390
18391 result // $ExpectType string
18392 })
18393 it('with string as search pattern', () => {
18394 const result = replace('foo', replacer, str)
18395
18396 result // $ExpectType string
18397 })
18398})
18399
18400describe('R.replace - curried', () => {
18401 it('happy', () => {
18402 const result = replace(/foo/g, replacer)(str)
18403
18404 result // $ExpectType string
18405 })
18406 it('with string as search pattern', () => {
18407 const result = replace('foo', replacer)(str)
18408
18409 result // $ExpectType string
18410 })
18411})
18412```
18413
18414</details>
18415
18416[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#replace)
18417
18418### reverse
18419
18420```typescript
18421
18422reverse<T>(input: readonly T[]): T[]
18423```
18424
18425It returns a reversed copy of list or string `input`.
18426
18427```javascript
18428const result = [
18429 R.reverse('foo'),
18430 R.reverse([1, 2, 3])
18431]
18432// => ['oof', [3, 2, 1]
18433```
18434
18435<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.reverse('foo')%2C%0A%20%20R.reverse(%5B1%2C%202%2C%203%5D)%0A%5D%0A%2F%2F%20%3D%3E%20%5B'oof'%2C%20%5B3%2C%202%2C%201%5D">Try this <strong>R.reverse</strong> example in Rambda REPL</a>
18436
18437<details>
18438
18439<summary>All Typescript definitions</summary>
18440
18441```typescript
18442reverse<T>(input: readonly T[]): T[];
18443reverse(input: string): string;
18444```
18445
18446</details>
18447
18448<details>
18449
18450<summary><strong>R.reverse</strong> source</summary>
18451
18452```javascript
18453export function reverse(listOrString){
18454 if (typeof listOrString === 'string'){
18455 return listOrString.split('').reverse()
18456 .join('')
18457 }
18458
18459 const clone = listOrString.slice()
18460
18461 return clone.reverse()
18462}
18463```
18464
18465</details>
18466
18467<details>
18468
18469<summary><strong>Tests</strong></summary>
18470
18471```javascript
18472import { reverse } from './reverse'
18473
18474test('happy', () => {
18475 expect(reverse([ 1, 2, 3 ])).toEqual([ 3, 2, 1 ])
18476})
18477
18478test('with string', () => {
18479 expect(reverse('baz')).toEqual('zab')
18480})
18481
18482test('it doesn\'t mutate', () => {
18483 const arr = [ 1, 2, 3 ]
18484
18485 expect(reverse(arr)).toEqual([ 3, 2, 1 ])
18486
18487 expect(arr).toEqual([ 1, 2, 3 ])
18488})
18489```
18490
18491</details>
18492
18493<details>
18494
18495<summary><strong>Typescript</strong> test</summary>
18496
18497```typescript
18498import {reverse} from 'rambda'
18499
18500const list = [1, 2, 3, 4, 5]
18501
18502describe('R.reverse', () => {
18503 it('happy', () => {
18504 const result = reverse(list)
18505 result // $ExpectType number[]
18506 })
18507})
18508```
18509
18510</details>
18511
18512[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#reverse)
18513
18514### set
18515
18516```typescript
18517
18518set<T, U>(lens: Lens, replacer: U, obj: T): T
18519```
18520
18521It returns a copied **Object** or **Array** with modified `lens` focus set to `replacer` value.
18522
18523```javascript
18524const input = {x: 1, y: 2}
18525const xLens = R.lensProp('x')
18526
18527R.set(xLens, 4, input) //=> {x: 4, y: 2}
18528R.set(xLens, 8, input) //=> {x: 8, y: 2}
18529```
18530
18531<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20input%20%3D%20%7Bx%3A%201%2C%20y%3A%202%7D%0Aconst%20xLens%20%3D%20R.lensProp('x')%0A%0AR.set(xLens%2C%204%2C%20input)%20%2F%2F%3D%3E%20%7Bx%3A%204%2C%20y%3A%202%7D%0AR.set(xLens%2C%208%2C%20input)%20%2F%2F%3D%3E%20%7Bx%3A%208%2C%20y%3A%202%7D">Try this <strong>R.set</strong> example in Rambda REPL</a>
18532
18533<details>
18534
18535<summary>All Typescript definitions</summary>
18536
18537```typescript
18538set<T, U>(lens: Lens, replacer: U, obj: T): T;
18539set<U>(lens: Lens, replacer: U): <T>(obj: T) => T;
18540set(lens: Lens): <T, U>(replacer: U, obj: T) => T;
18541```
18542
18543</details>
18544
18545<details>
18546
18547<summary><strong>R.set</strong> source</summary>
18548
18549```javascript
18550import { always } from './always'
18551import { curry } from './curry'
18552import { over } from './over'
18553
18554function setFn(
18555 lens, replacer, x
18556){
18557 return over(
18558 lens, always(replacer), x
18559 )
18560}
18561
18562export const set = curry(setFn)
18563```
18564
18565</details>
18566
18567<details>
18568
18569<summary><strong>Tests</strong></summary>
18570
18571```javascript
18572import { assoc } from './assoc'
18573import { lens } from './lens'
18574import { lensIndex } from './lensIndex'
18575import { lensPath } from './lensPath'
18576import { prop } from './prop'
18577import { set } from './set'
18578
18579const testObject = {
18580 foo : 'bar',
18581 baz : {
18582 a : 'x',
18583 b : 'y',
18584 },
18585}
18586
18587test('assoc lens', () => {
18588 const assocLens = lens(prop('foo'), assoc('foo'))
18589 const result = set(
18590 assocLens, 'FOO', testObject
18591 )
18592 const expected = {
18593 ...testObject,
18594 foo : 'FOO',
18595 }
18596 expect(result).toEqual(expected)
18597})
18598
18599test('path lens', () => {
18600 const pathLens = lensPath('baz.a')
18601 const result = set(
18602 pathLens, 'z', testObject
18603 )
18604 const expected = {
18605 ...testObject,
18606 baz : {
18607 a : 'z',
18608 b : 'y',
18609 },
18610 }
18611 expect(result).toEqual(expected)
18612})
18613
18614test('index lens', () => {
18615 const indexLens = lensIndex(0)
18616
18617 const result = set(
18618 indexLens, 3, [ 1, 2 ]
18619 )
18620 expect(result).toEqual([ 3, 2 ])
18621})
18622```
18623
18624</details>
18625
18626[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#set)
18627
18628### slice
18629
18630```typescript
18631
18632slice(from: number, to: number, input: string): string
18633```
18634
18635```javascript
18636const list = [0, 1, 2, 3, 4, 5]
18637const str = 'FOO_BAR'
18638const from = 1
18639const to = 4
18640
18641const result = [
18642 R.slice(str, to, list),
18643 R.slice(from, to, list)
18644]
18645// => ['OO_', [1, 2, 3]]
18646```
18647
18648<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B0%2C%201%2C%202%2C%203%2C%204%2C%205%5D%0Aconst%20str%20%3D%20'FOO_BAR'%0Aconst%20from%20%3D%201%0Aconst%20to%20%3D%204%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.slice(str%2C%20to%2C%20list)%2C%0A%20%20R.slice(from%2C%20to%2C%20list)%0A%5D%0A%2F%2F%20%3D%3E%20%5B'OO_'%2C%20%5B1%2C%202%2C%203%5D%5D">Try this <strong>R.slice</strong> example in Rambda REPL</a>
18649
18650<details>
18651
18652<summary>All Typescript definitions</summary>
18653
18654```typescript
18655slice(from: number, to: number, input: string): string;
18656slice<T>(from: number, to: number, input: readonly T[]): T[];
18657slice(from: number, to: number): {
18658 (input: string): string;
18659 <T>(input: readonly T[]): T[];
18660};
18661slice(from: number): {
18662 (to: number, input: string): string;
18663 <T>(to: number, input: readonly T[]): T[];
18664};
18665```
18666
18667</details>
18668
18669<details>
18670
18671<summary><strong>R.slice</strong> source</summary>
18672
18673```javascript
18674import { curry } from './curry'
18675
18676function sliceFn(
18677 from, to, list
18678){
18679 return list.slice(from, to)
18680}
18681
18682export const slice = curry(sliceFn)
18683```
18684
18685</details>
18686
18687<details>
18688
18689<summary><strong>Tests</strong></summary>
18690
18691```javascript
18692import { slice } from './slice'
18693
18694test('slice', () => {
18695 expect(slice(
18696 1, 3, [ 'a', 'b', 'c', 'd' ]
18697 )).toEqual([ 'b', 'c' ])
18698 expect(slice(
18699 1, Infinity, [ 'a', 'b', 'c', 'd' ]
18700 )).toEqual([ 'b', 'c', 'd' ])
18701 expect(slice(
18702 0, -1, [ 'a', 'b', 'c', 'd' ]
18703 )).toEqual([ 'a', 'b', 'c' ])
18704 expect(slice(
18705 -3, -1, [ 'a', 'b', 'c', 'd' ]
18706 )).toEqual([ 'b', 'c' ])
18707 expect(slice(
18708 0, 3, 'ramda'
18709 )).toEqual('ram')
18710})
18711```
18712
18713</details>
18714
18715<details>
18716
18717<summary><strong>Typescript</strong> test</summary>
18718
18719```typescript
18720import {slice} from 'rambda'
18721
18722const list = [1, 2, 3, 4, 5]
18723
18724describe('R.slice', () => {
18725 it('happy', () => {
18726 const result = slice(1, 3, list)
18727 result // $ExpectType number[]
18728 })
18729 it('curried', () => {
18730 const result = slice(1, 3)(list)
18731 result // $ExpectType number[]
18732 })
18733})
18734```
18735
18736</details>
18737
18738[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#slice)
18739
18740### sort
18741
18742```typescript
18743
18744sort<T>(sortFn: (a: T, b: T) => number, list: readonly T[]): T[]
18745```
18746
18747It returns copy of `list` sorted by `sortFn` function.
18748
18749> :boom: `sortFn` function must return a number.
18750
18751```javascript
18752const list = [
18753 {a: 2},
18754 {a: 3},
18755 {a: 1}
18756]
18757const sortFn = (x, y) => {
18758 return x.a > y.a ? 1 : -1
18759}
18760
18761const result = R.sort(sortFn, list)
18762const expected = [
18763 {a: 1},
18764 {a: 2},
18765 {a: 3}
18766]
18767// => `result` is equal to `expected`
18768```
18769
18770<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%0A%20%20%7Ba%3A%202%7D%2C%0A%20%20%7Ba%3A%203%7D%2C%0A%20%20%7Ba%3A%201%7D%0A%5D%0Aconst%20sortFn%20%3D%20(x%2C%20y)%20%3D%3E%20%7B%0A%20%20return%20x.a%20%3E%20y.a%20%3F%201%20%3A%20-1%0A%7D%0A%0Aconst%20result%20%3D%20R.sort(sortFn%2C%20list)%0Aconst%20expected%20%3D%20%5B%0A%20%20%7Ba%3A%201%7D%2C%0A%20%20%7Ba%3A%202%7D%2C%0A%20%20%7Ba%3A%203%7D%0A%5D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.sort</strong> example in Rambda REPL</a>
18771
18772<details>
18773
18774<summary>All Typescript definitions</summary>
18775
18776```typescript
18777sort<T>(sortFn: (a: T, b: T) => number, list: readonly T[]): T[];
18778sort<T>(sortFn: (a: T, b: T) => number): (list: readonly T[]) => T[];
18779```
18780
18781</details>
18782
18783<details>
18784
18785<summary><strong>R.sort</strong> source</summary>
18786
18787```javascript
18788export function sort(sortFn, list){
18789 if (arguments.length === 1) return _list => sort(sortFn, _list)
18790
18791 const clone = list.slice()
18792
18793 return clone.sort(sortFn)
18794}
18795```
18796
18797</details>
18798
18799<details>
18800
18801<summary><strong>Tests</strong></summary>
18802
18803```javascript
18804import { sort } from './sort'
18805
18806const fn = (a, b) => a > b ? 1 : -1
18807
18808test('sort', () => {
18809 expect(sort((a, b) => a - b)([ 2, 3, 1 ])).toEqual([ 1, 2, 3 ])
18810})
18811
18812test('it doesn\'t mutate', () => {
18813 const list = [ 'foo', 'bar', 'baz' ]
18814
18815 expect(sort(fn, list)).toEqual([ 'bar', 'baz', 'foo' ])
18816
18817 expect(list[ 0 ]).toBe('foo')
18818 expect(list[ 1 ]).toBe('bar')
18819 expect(list[ 2 ]).toBe('baz')
18820})
18821```
18822
18823</details>
18824
18825<details>
18826
18827<summary><strong>Typescript</strong> test</summary>
18828
18829```typescript
18830import {sort} from 'rambda'
18831
18832const list = [3, 0, 5, 2, 1]
18833
18834function sortFn(a: number, b: number): number {
18835 return a > b ? 1 : -1
18836}
18837
18838describe('R.sort', () => {
18839 it('happy', () => {
18840 const result = sort(sortFn, list)
18841 result // $ExpectType number[]
18842 })
18843 it('curried', () => {
18844 const result = sort(sortFn)(list)
18845 result // $ExpectType number[]
18846 })
18847})
18848```
18849
18850</details>
18851
18852[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#sort)
18853
18854### sortBy
18855
18856```typescript
18857
18858sortBy<T>(sortFn: (a: T) => Ord, list: readonly T[]): T[]
18859```
18860
18861It returns copy of `list` sorted by `sortFn` function.
18862
18863> :boom: `sortFn` function must return a value to compare.
18864
18865```javascript
18866const list = [
18867 {a: 2},
18868 {a: 3},
18869 {a: 1}
18870]
18871const sortFn = x => x.a
18872
18873const result = R.sortBy(sortFn, list)
18874const expected = [
18875 {a: 1},
18876 {a: 2},
18877 {a: 3}
18878]
18879// => `result` is equal to `expected`
18880```
18881
18882<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%0A%20%20%7Ba%3A%202%7D%2C%0A%20%20%7Ba%3A%203%7D%2C%0A%20%20%7Ba%3A%201%7D%0A%5D%0Aconst%20sortFn%20%3D%20x%20%3D%3E%20x.a%0A%0Aconst%20result%20%3D%20R.sortBy(sortFn%2C%20list)%0Aconst%20expected%20%3D%20%5B%0A%20%20%7Ba%3A%201%7D%2C%0A%20%20%7Ba%3A%202%7D%2C%0A%20%20%7Ba%3A%203%7D%0A%5D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.sortBy</strong> example in Rambda REPL</a>
18883
18884<details>
18885
18886<summary>All Typescript definitions</summary>
18887
18888```typescript
18889sortBy<T>(sortFn: (a: T) => Ord, list: readonly T[]): T[];
18890sortBy(sortFn: (a: any) => Ord): <T>(list: readonly T[]) => T[];
18891```
18892
18893</details>
18894
18895<details>
18896
18897<summary><strong>R.sortBy</strong> source</summary>
18898
18899```javascript
18900export function sortBy(sortFn, list){
18901 if (arguments.length === 1) return _list => sortBy(sortFn, _list)
18902
18903 const clone = list.slice()
18904
18905 return clone.sort((a, b) => {
18906 const aSortResult = sortFn(a)
18907 const bSortResult = sortFn(b)
18908
18909 if (aSortResult === bSortResult) return 0
18910
18911 return aSortResult < bSortResult ? -1 : 1
18912 })
18913}
18914```
18915
18916</details>
18917
18918<details>
18919
18920<summary><strong>Tests</strong></summary>
18921
18922```javascript
18923import { compose } from './compose'
18924import { prop } from './prop'
18925import { sortBy } from './sortBy'
18926import { toLower } from './toLower'
18927
18928test('happy', () => {
18929 const input = [ { a : 2 }, { a : 1 }, { a : 1 }, { a : 3 } ]
18930 const expected = [ { a : 1 }, { a : 1 }, { a : 2 }, { a : 3 } ]
18931
18932 const result = sortBy(x => x.a)(input)
18933 expect(result).toEqual(expected)
18934})
18935
18936test('with compose', () => {
18937 const alice = {
18938 name : 'ALICE',
18939 age : 101,
18940 }
18941 const bob = {
18942 name : 'Bob',
18943 age : -10,
18944 }
18945 const clara = {
18946 name : 'clara',
18947 age : 314.159,
18948 }
18949 const people = [ clara, bob, alice ]
18950 const sortByNameCaseInsensitive = sortBy(compose(toLower, prop('name')))
18951
18952 expect(sortByNameCaseInsensitive(people)).toEqual([ alice, bob, clara ])
18953})
18954```
18955
18956</details>
18957
18958<details>
18959
18960<summary><strong>Typescript</strong> test</summary>
18961
18962```typescript
18963import {sortBy} from 'rambda'
18964
18965interface Input {
18966 a: number,
18967}
18968
18969describe('R.sortBy', () => {
18970 it('passing type to sort function', () => {
18971 function fn(x: any): number {
18972 return x.a
18973 }
18974 function fn2(x: Input): number {
18975 return x.a
18976 }
18977
18978 const input = [{a: 2}, {a: 1}, {a: 0}]
18979 const result = sortBy(fn, input)
18980 const curriedResult = sortBy(fn2)(input)
18981
18982 result // $ExpectType { a: number; }[]
18983 curriedResult // $ExpectType { a: number; }[]
18984 result[0].a // $ExpectType number
18985 })
18986 it('passing type to sort function and list', () => {
18987 function fn(x: Input): number {
18988 return x.a
18989 }
18990
18991 const input: Input[] = [{a: 2}, {a: 1}, {a: 0}]
18992 const result = sortBy(fn, input)
18993 const curriedResult = sortBy(fn)(input)
18994
18995 result // $ExpectType Input[]
18996 curriedResult // $ExpectType Input[]
18997 result[0].a // $ExpectType number
18998 })
18999})
19000```
19001
19002</details>
19003
19004<details>
19005
19006<summary>1 failed <italic>Ramda.sortBy</italic> specs
19007
19008> :boom: Reason for the failure: Ramda method works with array-like objects
19009</summary>
19010
19011```javascript
19012var R = require('../../../../dist/rambda.js');
19013var eq = require('./shared/eq');
19014
19015var albums = [
19016 {title: 'Art of the Fugue', artist: 'Glenn Gould', genre: 'Baroque'},
19017 {title: 'A Farewell to Kings', artist: 'Rush', genre: 'Rock'},
19018 {title: 'Timeout', artist: 'Dave Brubeck Quartet', genre: 'Jazz'},
19019 {title: 'Fly By Night', artist: 'Rush', genre: 'Rock'},
19020 {title: 'Goldberg Variations', artist: 'Daniel Barenboim', genre: 'Baroque'},
19021 {title: 'New World Symphony', artist: 'Leonard Bernstein', genre: 'Romantic'},
19022 {title: 'Romance with the Unseen', artist: 'Don Byron', genre: 'Jazz'},
19023 {title: 'Somewhere In Time', artist: 'Iron Maiden', genre: 'Metal'},
19024 {title: 'In Times of Desparation', artist: 'Danny Holt', genre: 'Modern'},
19025 {title: 'Evita', artist: 'Various', genre: 'Broadway'},
19026 {title: 'Five Leaves Left', artist: 'Nick Drake', genre: 'Folk'},
19027 {title: 'The Magic Flute', artist: 'John Eliot Gardiner', genre: 'Classical'}
19028];
19029describe('sortBy', function() {
19030 it('sorts array-like object', function() {
19031 var args = (function() { return arguments; }('c', 'a', 'b'));
19032 var result = R.sortBy(R.identity, args);
19033 eq(result[0], 'a');
19034 eq(result[1], 'b');
19035 eq(result[2], 'c');
19036 });
19037});
19038```
19039
19040</details>
19041
19042[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#sortBy)
19043
19044### split
19045
19046```typescript
19047
19048split(separator: string | RegExp): (str: string) => string[]
19049```
19050
19051Curried version of `String.prototype.split`
19052
19053```javascript
19054const str = 'foo|bar|baz'
19055const separator = |'
19056const result = R.split(separator, str))
19057// => [ 'foo', 'bar', 'baz' ]
19058```
19059
19060<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20str%20%3D%20'foo%7Cbar%7Cbaz'%0Aconst%20separator%20%3D%20%7C'%0Aconst%20result%20%3D%20R.split(separator%2C%20str))%0A%2F%2F%20%3D%3E%20%5B%20'foo'%2C%20'bar'%2C%20'baz'%20%5D">Try this <strong>R.split</strong> example in Rambda REPL</a>
19061
19062<details>
19063
19064<summary>All Typescript definitions</summary>
19065
19066```typescript
19067split(separator: string | RegExp): (str: string) => string[];
19068split(separator: string | RegExp, str: string): string[];
19069```
19070
19071</details>
19072
19073<details>
19074
19075<summary><strong>R.split</strong> source</summary>
19076
19077```javascript
19078export function split(separator, str){
19079 if (arguments.length === 1) return _str => split(separator, _str)
19080
19081 return str.split(separator)
19082}
19083```
19084
19085</details>
19086
19087<details>
19088
19089<summary><strong>Tests</strong></summary>
19090
19091```javascript
19092import { split } from './split'
19093
19094const str = 'foo|bar|baz'
19095const splitChar = '|'
19096const expected = [ 'foo', 'bar', 'baz' ]
19097
19098test('happy', () => {
19099 expect(split(splitChar, str)).toEqual(expected)
19100})
19101
19102test('curried', () => {
19103 expect(split(splitChar)(str)).toEqual(expected)
19104})
19105```
19106
19107</details>
19108
19109<details>
19110
19111<summary><strong>Typescript</strong> test</summary>
19112
19113```typescript
19114import {split} from 'rambda'
19115
19116const str = 'foo|bar|baz'
19117const splitChar = '|'
19118
19119describe('R.split', () => {
19120 it('happy', () => {
19121 const result = split(splitChar, str)
19122
19123 result // $ExpectType string[]
19124 })
19125 it('curried', () => {
19126 const result = split(splitChar)(str)
19127
19128 result // $ExpectType string[]
19129 })
19130})
19131```
19132
19133</details>
19134
19135[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#split)
19136
19137### splitAt
19138
19139```typescript
19140
19141splitAt<T>(index: number, input: T[]): [T[], T[]]
19142```
19143
19144It splits string or array at a given index.
19145
19146```javascript
19147const list = [ 1, 2, 3 ]
19148const result = splitAt(2, list)
19149// => [[ 1, 2 ], [ 3 ]]
19150```
19151
19152<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%201%2C%202%2C%203%20%5D%0Aconst%20result%20%3D%20splitAt(2%2C%20list)%0A%2F%2F%20%3D%3E%20%5B%5B%201%2C%202%20%5D%2C%20%5B%203%20%5D%5D">Try this <strong>R.splitAt</strong> example in Rambda REPL</a>
19153
19154<details>
19155
19156<summary>All Typescript definitions</summary>
19157
19158```typescript
19159splitAt<T>(index: number, input: T[]): [T[], T[]];
19160splitAt(index: number, input: string): [string, string];
19161splitAt(index: number): {
19162 <T>(input: T[]): [T[], T[]];
19163 (input: string): [string, string];
19164};
19165```
19166
19167</details>
19168
19169<details>
19170
19171<summary><strong>R.splitAt</strong> source</summary>
19172
19173```javascript
19174import { _isArray } from './_internals/_isArray'
19175import { drop } from './drop'
19176import { maybe } from './maybe'
19177import { take } from './take'
19178
19179export function splitAt(index, input){
19180 if (arguments.length === 1){
19181 return _list => splitAt(index, _list)
19182 }
19183 if (!input) throw new TypeError(`Cannot read property 'slice' of ${ input }`)
19184
19185 if (!_isArray(input) && typeof input !== 'string') return [ [], [] ]
19186
19187 const correctIndex = maybe(
19188 index < 0,
19189 input.length + index < 0 ? 0 : input.length + index,
19190 index
19191 )
19192
19193 return [ take(correctIndex, input), drop(correctIndex, input) ]
19194}
19195```
19196
19197</details>
19198
19199<details>
19200
19201<summary><strong>Tests</strong></summary>
19202
19203```javascript
19204import { splitAt as splitAtRamda } from 'ramda'
19205
19206import { splitAt } from './splitAt'
19207
19208const list = [ 1, 2, 3 ]
19209const str = 'foo bar'
19210
19211test('with array', () => {
19212 const result = splitAt(2, list)
19213 expect(result).toEqual([ [ 1, 2 ], [ 3 ] ])
19214})
19215
19216test('with array - index is negative number', () => {
19217 const result = splitAt(-6, list)
19218 expect(result).toEqual([ [], list ])
19219})
19220
19221test('with array - index is out of scope', () => {
19222 const result = splitAt(4, list)
19223 expect(result).toEqual([ [ 1, 2, 3 ], [] ])
19224})
19225
19226test('with string', () => {
19227 const result = splitAt(4, str)
19228 expect(result).toEqual([ 'foo ', 'bar' ])
19229})
19230
19231test('with string - index is negative number', () => {
19232 const result = splitAt(-2, str)
19233 expect(result).toEqual([ 'foo b', 'ar' ])
19234})
19235
19236test('with string - index is out of scope', () => {
19237 const result = splitAt(10, str)
19238 expect(result).toEqual([ str, '' ])
19239})
19240
19241test('with array - index is out of scope', () => {
19242 const result = splitAt(4)(list)
19243 expect(result).toEqual([ [ 1, 2, 3 ], [] ])
19244})
19245
19246const badInputs = [ 1, true, /foo/g, {} ]
19247const throwingBadInputs = [ null, undefined ]
19248
19249test('with bad inputs', () => {
19250 throwingBadInputs.forEach(badInput => {
19251 expect(() => splitAt(1, badInput)).toThrowWithMessage(TypeError,
19252 `Cannot read property 'slice' of ${ badInput }`)
19253 expect(() => splitAtRamda(1, badInput)).toThrowWithMessage(TypeError,
19254 `Cannot read property 'slice' of ${ badInput }`)
19255 })
19256
19257 badInputs.forEach(badInput => {
19258 const result = splitAt(1, badInput)
19259 const ramdaResult = splitAtRamda(1, badInput)
19260 expect(result).toEqual(ramdaResult)
19261 })
19262})
19263```
19264
19265</details>
19266
19267<details>
19268
19269<summary><strong>Typescript</strong> test</summary>
19270
19271```typescript
19272import {splitAt} from 'ramda'
19273
19274const index = 1
19275const str = 'foo'
19276const list = [1, 2, 3]
19277
19278describe('R.splitAt with array', () => {
19279 it('happy', () => {
19280 const result = splitAt(index, list)
19281
19282 result // $ExpectType [number[], number[]]
19283 })
19284 it('curried', () => {
19285 const result = splitAt(index)(list)
19286
19287 result // $ExpectType [number[], number[]]
19288 })
19289})
19290
19291describe('R.splitAt with string', () => {
19292 it('happy', () => {
19293 const result = splitAt(index, str)
19294
19295 result // $ExpectType [string, string]
19296 })
19297 it('curried', () => {
19298 const result = splitAt(index)(str)
19299
19300 result // $ExpectType [string, string]
19301 })
19302})
19303```
19304
19305</details>
19306
19307[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#splitAt)
19308
19309### splitEvery
19310
19311```typescript
19312
19313splitEvery<T>(sliceLength: number, input: readonly T[]): T[][]
19314```
19315
19316It splits `input` into slices of `sliceLength`.
19317
19318```javascript
19319const result = [
19320 R.splitEvery(2, [1, 2, 3]),
19321 R.splitEvery(3, 'foobar')
19322]
19323
19324const expected = [
19325 [[1, 2], [3]],
19326 ['foo', 'bar']
19327]
19328// => `result` is equal to `expected`
19329```
19330
19331<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.splitEvery(2%2C%20%5B1%2C%202%2C%203%5D)%2C%20%0A%20%20R.splitEvery(3%2C%20'foobar')%20%0A%5D%0A%0Aconst%20expected%20%3D%20%5B%0A%20%20%5B%5B1%2C%202%5D%2C%20%5B3%5D%5D%2C%0A%20%20%5B'foo'%2C%20'bar'%5D%0A%5D%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.splitEvery</strong> example in Rambda REPL</a>
19332
19333<details>
19334
19335<summary>All Typescript definitions</summary>
19336
19337```typescript
19338splitEvery<T>(sliceLength: number, input: readonly T[]): T[][];
19339splitEvery(sliceLength: number, input: string): string[];
19340splitEvery(sliceLength: number): {
19341 (input: string): string[];
19342 <T>(input: readonly T[]): T[][];
19343};
19344```
19345
19346</details>
19347
19348<details>
19349
19350<summary><strong>R.splitEvery</strong> source</summary>
19351
19352```javascript
19353export function splitEvery(sliceLength, listOrString){
19354 if (arguments.length === 1){
19355 return _listOrString => splitEvery(sliceLength, _listOrString)
19356 }
19357
19358 if (sliceLength < 1){
19359 throw new Error('First argument to splitEvery must be a positive integer')
19360 }
19361
19362 const willReturn = []
19363 let counter = 0
19364
19365 while (counter < listOrString.length){
19366 willReturn.push(listOrString.slice(counter, counter += sliceLength))
19367 }
19368
19369 return willReturn
19370}
19371```
19372
19373</details>
19374
19375<details>
19376
19377<summary><strong>Tests</strong></summary>
19378
19379```javascript
19380import { splitEvery } from './splitEvery'
19381
19382test('happy', () => {
19383 expect(splitEvery(3, [ 1, 2, 3, 4, 5, 6, 7 ])).toEqual([
19384 [ 1, 2, 3 ],
19385 [ 4, 5, 6 ],
19386 [ 7 ],
19387 ])
19388
19389 expect(splitEvery(3)('foobarbaz')).toEqual([ 'foo', 'bar', 'baz' ])
19390})
19391
19392test('with bad input', () => {
19393 expect(() =>
19394 expect(splitEvery(0)('foo')).toEqual([ 'f', 'o', 'o' ])).toThrowWithMessage(Error,
19395 'First argument to splitEvery must be a positive integer')
19396})
19397```
19398
19399</details>
19400
19401<details>
19402
19403<summary><strong>Typescript</strong> test</summary>
19404
19405```typescript
19406import {splitEvery} from 'rambda'
19407
19408const list = [1, 2, 3, 4, 5, 6, 7]
19409
19410describe('R.splitEvery', () => {
19411 it('happy', () => {
19412 const result = splitEvery(3, list)
19413
19414 result // $ExpectType number[][]
19415 })
19416 it('curried', () => {
19417 const result = splitEvery(3)(list)
19418
19419 result // $ExpectType number[][]
19420 })
19421})
19422```
19423
19424</details>
19425
19426[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#splitEvery)
19427
19428### splitWhen
19429
19430```typescript
19431
19432splitWhen<T, U>(predicate: Predicate<T>, list: U[]): U[][]
19433```
19434
19435It splits `list` to two arrays according to a `predicate` function.
19436
19437The first array contains all members of `list` before `predicate` returns `true`.
19438
19439```javascript
19440const list = [1, 2, 1, 2]
19441const result = R.splitWhen(R.equals(2), list)
19442// => [[1], [2, 1, 2]]
19443```
19444
19445<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%201%2C%202%5D%0Aconst%20result%20%3D%20R.splitWhen(R.equals(2)%2C%20list)%0A%2F%2F%20%3D%3E%20%5B%5B1%5D%2C%20%5B2%2C%201%2C%202%5D%5D">Try this <strong>R.splitWhen</strong> example in Rambda REPL</a>
19446
19447<details>
19448
19449<summary>All Typescript definitions</summary>
19450
19451```typescript
19452splitWhen<T, U>(predicate: Predicate<T>, list: U[]): U[][];
19453splitWhen<T>(predicate: Predicate<T>): <U>(list: U[]) => U[][];
19454```
19455
19456</details>
19457
19458<details>
19459
19460<summary><strong>R.splitWhen</strong> source</summary>
19461
19462```javascript
19463export function splitWhen(predicate, input){
19464 if (arguments.length === 1){
19465 return _input => splitWhen(predicate, _input)
19466 }
19467 if (!input)
19468 throw new TypeError(`Cannot read property 'length' of ${ input }`)
19469
19470 const preFound = []
19471 const postFound = []
19472 let found = false
19473 let counter = -1
19474
19475 while (counter++ < input.length - 1){
19476 if (found){
19477 postFound.push(input[ counter ])
19478 } else if (predicate(input[ counter ])){
19479 postFound.push(input[ counter ])
19480 found = true
19481 } else {
19482 preFound.push(input[ counter ])
19483 }
19484 }
19485
19486 return [ preFound, postFound ]
19487}
19488```
19489
19490</details>
19491
19492<details>
19493
19494<summary><strong>Tests</strong></summary>
19495
19496```javascript
19497import { splitWhen as splitWhenRamda } from 'ramda'
19498
19499import { equals } from './equals'
19500import { splitWhen } from './splitWhen'
19501
19502const list = [ 1, 2, 1, 2 ]
19503
19504test('happy', () => {
19505 const result = splitWhen(equals(2), list)
19506 expect(result).toEqual([ [ 1 ], [ 2, 1, 2 ] ])
19507})
19508
19509test('when predicate returns false', () => {
19510 const result = splitWhen(equals(3))(list)
19511 expect(result).toEqual([ list, [] ])
19512})
19513
19514const badInputs = [ 1, true, /foo/g, {} ]
19515const throwingBadInputs = [ null, undefined ]
19516
19517test('with bad inputs', () => {
19518 throwingBadInputs.forEach(badInput => {
19519 expect(() => splitWhen(equals(2), badInput)).toThrowWithMessage(TypeError,
19520 `Cannot read property 'length' of ${ badInput }`)
19521 expect(() => splitWhenRamda(equals(2), badInput)).toThrowWithMessage(TypeError,
19522 `Cannot read property 'length' of ${ badInput }`)
19523 })
19524
19525 badInputs.forEach(badInput => {
19526 const result = splitWhen(equals(2), badInput)
19527 const ramdaResult = splitWhenRamda(equals(2), badInput)
19528 expect(result).toEqual(ramdaResult)
19529 })
19530})
19531```
19532
19533</details>
19534
19535<details>
19536
19537<summary><strong>Typescript</strong> test</summary>
19538
19539```typescript
19540import {splitWhen} from 'rambda'
19541
19542const list = [1, 2, 1, 2]
19543const predicate = (x: number) => x === 2
19544
19545describe('R.splitWhen', () => {
19546 it('happy', () => {
19547 const result = splitWhen(predicate, list)
19548
19549 result // $ExpectType number[][]
19550 })
19551 it('curried', () => {
19552 const result = splitWhen(predicate)(list)
19553
19554 result // $ExpectType number[][]
19555 })
19556})
19557```
19558
19559</details>
19560
19561[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#splitWhen)
19562
19563### startsWith
19564
19565```typescript
19566
19567startsWith(target: string, str: string): boolean
19568```
19569
19570Curried version of `String.prototype.startsWith`
19571
19572> :boom: It doesn't work with arrays unlike its corresponding **Ramda** method.
19573
19574```javascript
19575const str = 'foo-bar'
19576
19577const result = [
19578 R.startsWith('foo', str),
19579 R.startsWith('bar', str)
19580]
19581// => [true, false]
19582```
19583
19584<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20str%20%3D%20'foo-bar'%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.startsWith('foo'%2C%20str)%2C%0A%20%20R.startsWith('bar'%2C%20str)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D">Try this <strong>R.startsWith</strong> example in Rambda REPL</a>
19585
19586<details>
19587
19588<summary>All Typescript definitions</summary>
19589
19590```typescript
19591startsWith(target: string, str: string): boolean;
19592startsWith(target: string): (str: string) => boolean;
19593```
19594
19595</details>
19596
19597<details>
19598
19599<summary><strong>R.startsWith</strong> source</summary>
19600
19601```javascript
19602export function startsWith(target, str){
19603 if (arguments.length === 1) return _str => startsWith(target, _str)
19604
19605 return str.startsWith(target)
19606}
19607```
19608
19609</details>
19610
19611<details>
19612
19613<summary><strong>Tests</strong></summary>
19614
19615```javascript
19616import { startsWith } from './startsWith'
19617
19618test('true', () => {
19619 const result = startsWith('foo', 'foo-bar')
19620
19621 expect(result).toBeTrue()
19622})
19623
19624test('false', () => {
19625 const result = startsWith('baz')('foo-bar')
19626
19627 expect(result).toBeFalse()
19628})
19629```
19630
19631</details>
19632
19633<details>
19634
19635<summary><strong>Typescript</strong> test</summary>
19636
19637```typescript
19638import {startsWith} from 'rambda'
19639
19640const target = 'foo'
19641const input = 'foo bar'
19642
19643describe('R.startsWith', () => {
19644 it('happy', () => {
19645 const result = startsWith(target, input)
19646
19647 result // $ExpectType boolean
19648 })
19649 it('curried', () => {
19650 const result = startsWith(target)(input)
19651
19652 result // $ExpectType boolean
19653 })
19654})
19655```
19656
19657</details>
19658
19659<details>
19660
19661<summary>4 failed <italic>Ramda.startsWith</italic> specs
19662
19663> :boom: Reason for the failure: Rambda method doesn't support arrays
19664</summary>
19665
19666```javascript
19667var R = require('../../../../dist/rambda.js');
19668var eq = require('./shared/eq');
19669
19670describe('startsWith', function() {
19671 it('should return true when an array starts with the provided value', function() {
19672 eq(R.startsWith(['a'], ['a', 'b', 'c']), true);
19673 });
19674 it('should return true when an array starts with the provided values', function() {
19675 eq(R.startsWith(['a', 'b'], ['a', 'b', 'c']), true);
19676 });
19677 it('should return false when an array does not start with the provided value', function() {
19678 eq(R.startsWith(['b'], ['a', 'b', 'c']), false);
19679 });
19680 it('should return false when an array does not start with the provided values', function() {
19681 eq(R.startsWith(['b', 'c'], ['a', 'b', 'c']), false);
19682 });
19683});
19684```
19685
19686</details>
19687
19688[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#startsWith)
19689
19690### subtract
19691
19692```typescript
19693
19694subtract(x: number, y: number): number
19695```
19696
19697Curried version of `x - y`
19698
19699```javascript
19700const x = 3
19701const y = 1
19702
19703R.subtract(x, y)
19704// => 2
19705```
19706
19707<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20x%20%3D%203%0Aconst%20y%20%3D%201%0A%0AR.subtract(x%2C%20y)%20%0A%2F%2F%20%3D%3E%202">Try this <strong>R.subtract</strong> example in Rambda REPL</a>
19708
19709<details>
19710
19711<summary>All Typescript definitions</summary>
19712
19713```typescript
19714subtract(x: number, y: number): number;
19715subtract(x: number): (y: number) => number;
19716```
19717
19718</details>
19719
19720<details>
19721
19722<summary><strong>R.subtract</strong> source</summary>
19723
19724```javascript
19725export function subtract(a, b){
19726 if (arguments.length === 1) return _b => subtract(a, _b)
19727
19728 return a - b
19729}
19730```
19731
19732</details>
19733
19734<details>
19735
19736<summary><strong>Tests</strong></summary>
19737
19738```javascript
19739import { subtract } from './subtract'
19740
19741test('happy', () => {
19742 expect(subtract(2, 1)).toEqual(1)
19743 expect(subtract(2)(1)).toEqual(1)
19744})
19745```
19746
19747</details>
19748
19749[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#subtract)
19750
19751### sum
19752
19753```typescript
19754
19755sum(list: readonly number[]): number
19756```
19757
19758```javascript
19759R.sum([1, 2, 3, 4, 5])
19760// => 15
19761```
19762
19763<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.sum(%5B1%2C%202%2C%203%2C%204%2C%205%5D)%20%0A%2F%2F%20%3D%3E%2015">Try this <strong>R.sum</strong> example in Rambda REPL</a>
19764
19765<details>
19766
19767<summary>All Typescript definitions</summary>
19768
19769```typescript
19770sum(list: readonly number[]): number;
19771```
19772
19773</details>
19774
19775<details>
19776
19777<summary><strong>R.sum</strong> source</summary>
19778
19779```javascript
19780export function sum(list){
19781 return list.reduce((prev, current) => prev + current, 0)
19782}
19783```
19784
19785</details>
19786
19787<details>
19788
19789<summary><strong>Tests</strong></summary>
19790
19791```javascript
19792import { sum } from './sum'
19793
19794test('happy', () => {
19795 expect(sum([ 1, 2, 3, 4, 5 ])).toBe(15)
19796})
19797```
19798
19799</details>
19800
19801[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#sum)
19802
19803### symmetricDifference
19804
19805```typescript
19806
19807symmetricDifference<T>(x: readonly T[], y: readonly T[]): T[]
19808```
19809
19810It returns a merged list of `x` and `y` with all equal elements removed.
19811
19812> :boom: `R.equals` is used to determine equality, i.e. it can be safely used with list of objects.
19813
19814```javascript
19815const x = [ 1, 2, 3, 4 ]
19816const y = [ 3, 4, 5, 6 ]
19817
19818const result = symmetricDifference(x, y)
19819// => [ 1, 2, 5, 6 ]
19820```
19821
19822<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20x%20%3D%20%5B%201%2C%202%2C%203%2C%204%20%5D%0Aconst%20y%20%3D%20%5B%203%2C%204%2C%205%2C%206%20%5D%0A%0Aconst%20result%20%3D%20symmetricDifference(x%2C%20y)%0A%2F%2F%20%3D%3E%20%5B%201%2C%202%2C%205%2C%206%20%5D">Try this <strong>R.symmetricDifference</strong> example in Rambda REPL</a>
19823
19824<details>
19825
19826<summary>All Typescript definitions</summary>
19827
19828```typescript
19829symmetricDifference<T>(x: readonly T[], y: readonly T[]): T[];
19830symmetricDifference<T>(x: readonly T[]): <T>(y: readonly T[]) => T[];
19831```
19832
19833</details>
19834
19835<details>
19836
19837<summary><strong>R.symmetricDifference</strong> source</summary>
19838
19839```javascript
19840import { concat } from './concat'
19841import { filter } from './filter'
19842import { includes } from './includes'
19843
19844export function symmetricDifference(x, y){
19845 if (arguments.length === 1){
19846 return _y => symmetricDifference(x, _y)
19847 }
19848
19849 return concat(filter(value => !includes(value, y), x),
19850 filter(value => !includes(value, x), y))
19851}
19852```
19853
19854</details>
19855
19856<details>
19857
19858<summary><strong>Tests</strong></summary>
19859
19860```javascript
19861import { symmetricDifference } from './symmetricDifference'
19862
19863test('symmetricDifference', () => {
19864 const list1 = [ 1, 2, 3, 4 ]
19865 const list2 = [ 3, 4, 5, 6 ]
19866 expect(symmetricDifference(list1)(list2)).toEqual([ 1, 2, 5, 6 ])
19867
19868 expect(symmetricDifference([], [])).toEqual([])
19869})
19870
19871test('symmetricDifference with objects', () => {
19872 const list1 = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
19873 const list2 = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
19874 expect(symmetricDifference(list1)(list2)).toEqual([
19875 { id : 1 },
19876 { id : 2 },
19877 { id : 5 },
19878 { id : 6 },
19879 ])
19880})
19881```
19882
19883</details>
19884
19885<details>
19886
19887<summary><strong>Typescript</strong> test</summary>
19888
19889```typescript
19890import {symmetricDifference} from 'rambda'
19891
19892describe('R.symmetricDifference', () => {
19893 it('happy', () => {
19894 const list1 = [1, 2, 3, 4]
19895 const list2 = [3, 4, 5, 6]
19896 const result = symmetricDifference(list1, list2)
19897
19898 result // $ExpectType number[]
19899 })
19900
19901 it('curried', () => {
19902 const list1 = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]
19903 const list2 = [{id: 3}, {id: 4}, {id: 5}, {id: 6}]
19904 const result = symmetricDifference(list1)(list2)
19905
19906 result // $ExpectType { id: number; }[]
19907 })
19908})
19909```
19910
19911</details>
19912
19913[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#symmetricDifference)
19914
19915### T
19916
19917```typescript
19918
19919T(): boolean
19920```
19921
19922```javascript
19923R.T()
19924// => true
19925```
19926
19927<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.T()%20%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.T</strong> example in Rambda REPL</a>
19928
19929<details>
19930
19931<summary>All Typescript definitions</summary>
19932
19933```typescript
19934T(): boolean;
19935```
19936
19937</details>
19938
19939<details>
19940
19941<summary><strong>R.T</strong> source</summary>
19942
19943```javascript
19944export function T(){
19945 return true
19946}
19947```
19948
19949</details>
19950
19951[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#T)
19952
19953### tail
19954
19955```typescript
19956
19957tail<T>(input: readonly T[]): T[]
19958```
19959
19960It returns all but the first element of `input`.
19961
19962```javascript
19963const result = [
19964 R.tail([1, 2, 3]),
19965 R.tail('foo')
19966]
19967// => [[2, 3], 'oo']
19968```
19969
19970<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20R.tail(%5B1%2C%202%2C%203%5D)%2C%20%20%0A%20%20R.tail('foo')%20%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B2%2C%203%5D%2C%20'oo'%5D">Try this <strong>R.tail</strong> example in Rambda REPL</a>
19971
19972<details>
19973
19974<summary>All Typescript definitions</summary>
19975
19976```typescript
19977tail<T>(input: readonly T[]): T[];
19978tail(input: string): string;
19979```
19980
19981</details>
19982
19983<details>
19984
19985<summary><strong>R.tail</strong> source</summary>
19986
19987```javascript
19988import { drop } from './drop'
19989
19990export function tail(listOrString){
19991 return drop(1, listOrString)
19992}
19993```
19994
19995</details>
19996
19997<details>
19998
19999<summary><strong>Tests</strong></summary>
20000
20001```javascript
20002import { tail } from './tail'
20003
20004test('tail', () => {
20005 expect(tail([ 1, 2, 3 ])).toEqual([ 2, 3 ])
20006 expect(tail([ 1, 2 ])).toEqual([ 2 ])
20007 expect(tail([ 1 ])).toEqual([])
20008 expect(tail([])).toEqual([])
20009
20010 expect(tail('abc')).toEqual('bc')
20011 expect(tail('ab')).toEqual('b')
20012 expect(tail('a')).toEqual('')
20013 expect(tail('')).toEqual('')
20014})
20015```
20016
20017</details>
20018
20019<details>
20020
20021<summary><strong>Typescript</strong> test</summary>
20022
20023```typescript
20024import {tail} from 'rambda'
20025
20026describe('R.tail', () => {
20027 it('with string', () => {
20028 const result = tail('foo')
20029
20030 result // $ExpectType string
20031 })
20032 it('with list', () => {
20033 const result = tail([1, 2, 3])
20034
20035 result // $ExpectType number[]
20036 })
20037})
20038```
20039
20040</details>
20041
20042[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#tail)
20043
20044### take
20045
20046```typescript
20047
20048take<T>(howMany: number, input: readonly T[]): T[]
20049```
20050
20051It returns the first `howMany` elements of `input`.
20052
20053```javascript
20054const howMany = 2
20055
20056const result = [
20057 R.take(howMany, [1, 2, 3]),
20058 R.take(howMany, 'foobar'),
20059]
20060// => [[1, 2], 'fo']
20061```
20062
20063<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20howMany%20%3D%202%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.take(howMany%2C%20%5B1%2C%202%2C%203%5D)%2C%0A%20%20R.take(howMany%2C%20'foobar')%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%202%5D%2C%20'fo'%5D">Try this <strong>R.take</strong> example in Rambda REPL</a>
20064
20065<details>
20066
20067<summary>All Typescript definitions</summary>
20068
20069```typescript
20070take<T>(howMany: number, input: readonly T[]): T[];
20071take(howMany: number, input: string): string;
20072take<T>(howMany: number): {
20073 <T>(input: readonly T[]): T[];
20074 (input: string): string;
20075};
20076```
20077
20078</details>
20079
20080<details>
20081
20082<summary><strong>R.take</strong> source</summary>
20083
20084```javascript
20085import baseSlice from './_internals/baseSlice'
20086
20087export function take(howMany, listOrString){
20088 if (arguments.length === 1)
20089 return _listOrString => take(howMany, _listOrString)
20090 if (howMany < 0) return listOrString.slice()
20091 if (typeof listOrString === 'string') return listOrString.slice(0, howMany)
20092
20093 return baseSlice(
20094 listOrString, 0, howMany
20095 )
20096}
20097```
20098
20099</details>
20100
20101<details>
20102
20103<summary><strong>Tests</strong></summary>
20104
20105```javascript
20106import { take } from './take'
20107
20108test('happy', () => {
20109 const arr = [ 'foo', 'bar', 'baz' ]
20110
20111 expect(take(1, arr)).toEqual([ 'foo' ])
20112
20113 expect(arr).toEqual([ 'foo', 'bar', 'baz' ])
20114
20115 expect(take(2)([ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar' ])
20116 expect(take(3, [ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar', 'baz' ])
20117 expect(take(4, [ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar', 'baz' ])
20118 expect(take(3)('rambda')).toEqual('ram')
20119})
20120
20121test('with negative index', () => {
20122 expect(take(-1, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
20123 expect(take(-Infinity, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
20124})
20125
20126test('with zero index', () => {
20127 expect(take(0, [ 1, 2, 3 ])).toEqual([])
20128})
20129```
20130
20131</details>
20132
20133<details>
20134
20135<summary><strong>Typescript</strong> test</summary>
20136
20137```typescript
20138import {take} from 'rambda'
20139
20140const list = [1, 2, 3, 4]
20141const str = 'foobar'
20142const howMany = 2
20143
20144describe('R.take - array', () => {
20145 it('happy', () => {
20146 const result = take(howMany, list)
20147
20148 result // $ExpectType number[]
20149 })
20150 it('curried', () => {
20151 const result = take(howMany)(list)
20152
20153 result // $ExpectType number[]
20154 })
20155})
20156
20157describe('R.take - string', () => {
20158 it('happy', () => {
20159 const result = take(howMany, str)
20160
20161 result // $ExpectType string
20162 })
20163 it('curried', () => {
20164 const result = take(howMany)(str)
20165
20166 result // $ExpectType string
20167 })
20168})
20169```
20170
20171</details>
20172
20173<details>
20174
20175<summary>3 failed <italic>Ramda.take</italic> specs
20176
20177> :boom: Reason for the failure: Rambda library doesn't have 'R.into` method
20178</summary>
20179
20180```javascript
20181var assert = require('assert');
20182var sinon = require('sinon');
20183
20184var R = require('../../../../dist/rambda.js');
20185var eq = require('./shared/eq');
20186describe('take', function() {
20187 it('handles zero correctly (#1224)', function() {
20188 eq(R.into([], R.take(0), [1, 2, 3]), []);
20189 });
20190 it('steps correct number of times', function() {
20191 var spy = sinon.spy();
20192 R.into([], R.compose(R.map(spy), R.take(2)), [1, 2, 3]);
20193 sinon.assert.calledTwice(spy);
20194 });
20195 it('transducer called for every member of list if `n` is < 0', function() {
20196 var spy = sinon.spy();
20197 R.into([], R.compose(R.map(spy), R.take(-1)), [1, 2, 3]);
20198 sinon.assert.calledThrice(spy);
20199 });
20200});
20201```
20202
20203</details>
20204
20205[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#take)
20206
20207### takeLast
20208
20209```typescript
20210
20211takeLast<T>(howMany: number, input: readonly T[]): T[]
20212```
20213
20214It returns the last `howMany` elements of `input`.
20215
20216```javascript
20217const howMany = 2
20218
20219const result = [
20220 R.takeLast(howMany, [1, 2, 3]),
20221 R.takeLast(howMany, 'foobar'),
20222]
20223// => [[2, 3], 'ar']
20224```
20225
20226<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20howMany%20%3D%202%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.takeLast(howMany%2C%20%5B1%2C%202%2C%203%5D)%2C%0A%20%20R.takeLast(howMany%2C%20'foobar')%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5B%5B2%2C%203%5D%2C%20'ar'%5D">Try this <strong>R.takeLast</strong> example in Rambda REPL</a>
20227
20228<details>
20229
20230<summary>All Typescript definitions</summary>
20231
20232```typescript
20233takeLast<T>(howMany: number, input: readonly T[]): T[];
20234takeLast(howMany: number, input: string): string;
20235takeLast<T>(howMany: number): {
20236 <T>(input: readonly T[]): T[];
20237 (input: string): string;
20238};
20239```
20240
20241</details>
20242
20243<details>
20244
20245<summary><strong>R.takeLast</strong> source</summary>
20246
20247```javascript
20248import baseSlice from './_internals/baseSlice'
20249
20250export function takeLast(howMany, listOrString){
20251 if (arguments.length === 1)
20252 return _listOrString => takeLast(howMany, _listOrString)
20253
20254 const len = listOrString.length
20255 if (howMany < 0) return listOrString.slice()
20256 let numValue = howMany > len ? len : howMany
20257
20258 if (typeof listOrString === 'string')
20259 return listOrString.slice(len - numValue)
20260
20261 numValue = len - numValue
20262
20263 return baseSlice(
20264 listOrString, numValue, len
20265 )
20266}
20267```
20268
20269</details>
20270
20271<details>
20272
20273<summary><strong>Tests</strong></summary>
20274
20275```javascript
20276import { takeLast } from './takeLast'
20277
20278test('with arrays', () => {
20279 expect(takeLast(1, [ 'foo', 'bar', 'baz' ])).toEqual([ 'baz' ])
20280
20281 expect(takeLast(2)([ 'foo', 'bar', 'baz' ])).toEqual([ 'bar', 'baz' ])
20282
20283 expect(takeLast(3, [ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar', 'baz' ])
20284
20285 expect(takeLast(4, [ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar', 'baz' ])
20286
20287 expect(takeLast(10, [ 'foo', 'bar', 'baz' ])).toEqual([ 'foo', 'bar', 'baz' ])
20288})
20289
20290test('with strings', () => {
20291 expect(takeLast(3, 'rambda')).toEqual('bda')
20292
20293 expect(takeLast(7, 'rambda')).toEqual('rambda')
20294})
20295
20296test('with negative index', () => {
20297 expect(takeLast(-1, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
20298 expect(takeLast(-Infinity, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ])
20299})
20300```
20301
20302</details>
20303
20304<details>
20305
20306<summary><strong>Typescript</strong> test</summary>
20307
20308```typescript
20309import {takeLast} from 'rambda'
20310
20311const list = [1, 2, 3, 4]
20312const str = 'foobar'
20313const howMany = 2
20314
20315describe('R.takeLast - array', () => {
20316 it('happy', () => {
20317 const result = takeLast(howMany, list)
20318
20319 result // $ExpectType number[]
20320 })
20321 it('curried', () => {
20322 const result = takeLast(howMany)(list)
20323
20324 result // $ExpectType number[]
20325 })
20326})
20327
20328describe('R.takeLast - string', () => {
20329 it('happy', () => {
20330 const result = takeLast(howMany, str)
20331
20332 result // $ExpectType string
20333 })
20334 it('curried', () => {
20335 const result = takeLast(howMany)(str)
20336
20337 result // $ExpectType string
20338 })
20339})
20340```
20341
20342</details>
20343
20344[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#takeLast)
20345
20346### takeLastWhile
20347
20348```typescript
20349
20350takeLastWhile(predicate: (x: string) => boolean, input: string): string
20351```
20352
20353```javascript
20354const result = R.takeLastWhile(
20355 x => x > 2,
20356 [1, 2, 3, 4]
20357)
20358// => [3, 4]
20359```
20360
20361<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.takeLastWhile(%0A%20%20x%20%3D%3E%20x%20%3E%202%2C%0A%20%20%5B1%2C%202%2C%203%2C%204%5D%0A)%0A%2F%2F%20%3D%3E%20%5B3%2C%204%5D">Try this <strong>R.takeLastWhile</strong> example in Rambda REPL</a>
20362
20363<details>
20364
20365<summary>All Typescript definitions</summary>
20366
20367```typescript
20368takeLastWhile(predicate: (x: string) => boolean, input: string): string;
20369takeLastWhile(predicate: (x: string) => boolean): (input: string) => string;
20370takeLastWhile<T>(predicate: (x: T) => boolean, input: readonly T[]): T[];
20371takeLastWhile<T>(predicate: (x: T) => boolean): <T>(input: readonly T[]) => T[];
20372```
20373
20374</details>
20375
20376<details>
20377
20378<summary><strong>R.takeLastWhile</strong> source</summary>
20379
20380```javascript
20381import { _isArray } from './_internals/_isArray.js'
20382
20383export function takeLastWhile(predicate, input){
20384 if (arguments.length === 1){
20385 return _input => takeLastWhile(predicate, _input)
20386 }
20387 if (input.length === 0) return input
20388 let found = false
20389 const toReturn = []
20390 let counter = input.length
20391
20392 while (!found || counter === 0){
20393 counter--
20394 if (predicate(input[ counter ]) === false){
20395 found = true
20396 } else if (!found){
20397 toReturn.push(input[ counter ])
20398 }
20399 }
20400
20401 return _isArray(input) ? toReturn.reverse() : toReturn.reverse().join('')
20402}
20403```
20404
20405</details>
20406
20407<details>
20408
20409<summary><strong>Tests</strong></summary>
20410
20411```javascript
20412import { takeLastWhile } from './takeLastWhile'
20413const assert = require('assert')
20414
20415const list = [ 1, 2, 3, 4 ]
20416
20417test('happy', () => {
20418 const predicate = x => x > 2
20419 const result = takeLastWhile(predicate, list)
20420 expect(result).toEqual([ 3, 4 ])
20421})
20422
20423test('predicate is always true', () => {
20424 const predicate = x => x > 0
20425 const result = takeLastWhile(predicate)(list)
20426 expect(result).toEqual(list)
20427})
20428
20429test('predicate is always false', () => {
20430 const predicate = x => x < 0
20431 const result = takeLastWhile(predicate, list)
20432 expect(result).toEqual([])
20433})
20434
20435test('with string', () => {
20436 const result = takeLastWhile(x => x !== 'F', 'FOOBAR')
20437 expect(result).toEqual('OOBAR')
20438})
20439```
20440
20441</details>
20442
20443<details>
20444
20445<summary><strong>Typescript</strong> test</summary>
20446
20447```typescript
20448import {takeLastWhile} from 'rambda'
20449
20450const list = [1, 2, 3]
20451const str = 'FOO'
20452
20453describe('R.takeLastWhile', () => {
20454 it('with array', () => {
20455 const result = takeLastWhile(x => x > 1, list)
20456
20457 result // $ExpectType number[]
20458 })
20459 it('with array - curried', () => {
20460 const result = takeLastWhile(x => x > 1, list)
20461
20462 result // $ExpectType number[]
20463 })
20464 it('with string', () => {
20465 const result = takeLastWhile(x => x !== 'F', str)
20466
20467 result // $ExpectType string
20468 })
20469 it('with string - curried', () => {
20470 const result = takeLastWhile(x => x !== 'F')(str)
20471
20472 result // $ExpectType string
20473 })
20474})
20475```
20476
20477</details>
20478
20479[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#takeLastWhile)
20480
20481### takeWhile
20482
20483```typescript
20484
20485takeWhile(fn: Predicate<string>, iterable: string): string
20486```
20487
20488```javascript
20489const list = [1, 2, 3, 4]
20490const predicate = x => x < 3
20491
20492const result = R.takeWhile(predicate, list)
20493// => [1, 2]
20494```
20495
20496<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3C%203%0A%0Aconst%20result%20%3D%20R.takeWhile(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20%5B1%2C%202%5D">Try this <strong>R.takeWhile</strong> example in Rambda REPL</a>
20497
20498<details>
20499
20500<summary>All Typescript definitions</summary>
20501
20502```typescript
20503takeWhile(fn: Predicate<string>, iterable: string): string;
20504takeWhile(fn: Predicate<string>): (iterable: string) => string;
20505takeWhile<T>(fn: Predicate<T>, iterable: readonly T[]): T[];
20506takeWhile<T>(fn: Predicate<T>): (iterable: readonly T[]) => T[];
20507```
20508
20509</details>
20510
20511<details>
20512
20513<summary><strong>R.takeWhile</strong> source</summary>
20514
20515```javascript
20516import { _isArray } from '../src/_internals/_isArray'
20517
20518export function takeWhile(predicate, iterable){
20519 if (arguments.length === 1){
20520 return _iterable => takeWhile(predicate, _iterable)
20521 }
20522 const isArray = _isArray(iterable)
20523 if (!isArray && typeof iterable !== 'string'){
20524 throw new Error('`iterable` is neither list nor a string')
20525 }
20526 let flag = true
20527 const holder = []
20528 let counter = -1
20529
20530 while (counter++ < iterable.length - 1){
20531 if (!predicate(iterable[ counter ])){
20532 if (flag) flag = false
20533 } else if (flag){
20534 holder.push(iterable[ counter ])
20535 }
20536 }
20537 holder
20538
20539 return isArray ? holder : holder.join('')
20540}
20541```
20542
20543</details>
20544
20545<details>
20546
20547<summary><strong>Tests</strong></summary>
20548
20549```javascript
20550import { takeWhile as takeWhileRamda } from "ramda";
20551
20552import { takeWhile } from "./takeWhile";
20553import { compareCombinations } from "./_internals/testUtils";
20554
20555const list = [1, 2, 3, 4, 5];
20556
20557test("happy", () => {
20558 const result = takeWhile((x) => x < 3, list);
20559 expect(result).toEqual([1, 2]);
20560});
20561
20562test("always true", () => {
20563 const result = takeWhile((x) => true, list);
20564 expect(result).toEqual(list);
20565});
20566
20567test("always false", () => {
20568 const result = takeWhile((x) => 0, list);
20569 expect(result).toEqual([]);
20570});
20571
20572test("with string", () => {
20573 const result = takeWhile((x) => x !== "b", "foobar");
20574 console.log(result);
20575 expect(result).toBe("foo");
20576});
20577
20578const possiblePredicates = [
20579 null,
20580 undefined,
20581 () => 0,
20582 () => true,
20583 (x) => x !== "b",
20584 /foo/g,
20585 {},
20586 [],
20587];
20588
20589const possibleIterables = [
20590 null,
20591 undefined,
20592 [],
20593 {},
20594 1,
20595 "",
20596 "foobar",
20597 [""],
20598 [1, 2, 3, 4, 5],
20599];
20600
20601describe("brute force", () => {
20602 compareCombinations({
20603 firstInput: possiblePredicates,
20604 callback: (errorsCounters) => {
20605 expect(errorsCounters).toMatchInlineSnapshot(`
20606 Object {
20607 "ERRORS_MESSAGE_MISMATCH": 15,
20608 "ERRORS_TYPE_MISMATCH": 16,
20609 "RESULTS_MISMATCH": 0,
20610 "SHOULD_NOT_THROW": 16,
20611 "SHOULD_THROW": 0,
20612 }
20613 `);
20614 },
20615 secondInput: possibleIterables,
20616 fn: takeWhile,
20617 fnRamda: takeWhileRamda,
20618 });
20619});
20620```
20621
20622</details>
20623
20624<details>
20625
20626<summary><strong>Typescript</strong> test</summary>
20627
20628```typescript
20629import {takeWhile} from 'rambda'
20630
20631const list = [1, 2, 3, 4]
20632
20633describe('R.takeWhile', () => {
20634 it('happy', () => {
20635 const result = takeWhile(x => x > 2, list)
20636
20637 result // $ExpectType number[]
20638 })
20639 it('curried require explicit type', () => {
20640 const result = takeWhile<number>(x => x > 2)(list)
20641
20642 result // $ExpectType number[]
20643 })
20644})
20645
20646describe('with string as iterable', () => {
20647 const str = 'foobar'
20648 it('happy', () => {
20649 const result = takeWhile(x => x !== 'b', str)
20650
20651 result // $ExpectType string
20652 })
20653 it('curried require explicit type', () => {
20654 const result = takeWhile(x => x !== 'b')(str)
20655
20656 result // $ExpectType string
20657 })
20658})
20659```
20660
20661</details>
20662
20663*2 failed Ramda.takeWhile specs*
20664
20665> :boom: Reason for the failure: Ramda method works with strings not only arrays
20666
20667[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#takeWhile)
20668
20669### tap
20670
20671```typescript
20672
20673tap<T>(fn: (x: T) => void, input: T): T
20674```
20675
20676It applies function `fn` to input `x` and returns `x`.
20677
20678One use case is debuging in the middle of `R.compose`.
20679
20680```javascript
20681const list = [1, 2, 3]
20682
20683R.compose(
20684 R.map(x => x * 2)
20685 R.tap(console.log),
20686 R.filter(x => x > 1)
20687)(list)
20688// => `2` and `3` will be logged
20689```
20690
20691<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0A%0AR.compose(%0A%20%20R.map(x%20%3D%3E%20x%20*%202)%0A%20%20R.tap(console.log)%2C%0A%20%20R.filter(x%20%3D%3E%20x%20%3E%201)%0A)(list)%0A%2F%2F%20%3D%3E%20%602%60%20and%20%603%60%20will%20be%20logged">Try this <strong>R.tap</strong> example in Rambda REPL</a>
20692
20693<details>
20694
20695<summary>All Typescript definitions</summary>
20696
20697```typescript
20698tap<T>(fn: (x: T) => void, input: T): T;
20699tap<T>(fn: (x: T) => void): (input: T) => T;
20700```
20701
20702</details>
20703
20704<details>
20705
20706<summary><strong>R.tap</strong> source</summary>
20707
20708```javascript
20709export function tap(fn, x){
20710 if (arguments.length === 1) return _x => tap(fn, _x)
20711
20712 fn(x)
20713
20714 return x
20715}
20716```
20717
20718</details>
20719
20720<details>
20721
20722<summary><strong>Tests</strong></summary>
20723
20724```javascript
20725import { tap } from './tap'
20726
20727test('tap', () => {
20728 let a = 1
20729 const sayX = x => a = x
20730
20731 expect(tap(sayX, 100)).toEqual(100)
20732 expect(tap(sayX)(100)).toEqual(100)
20733 expect(a).toEqual(100)
20734})
20735```
20736
20737</details>
20738
20739<details>
20740
20741<summary><strong>Typescript</strong> test</summary>
20742
20743```typescript
20744import {tap, pipe} from 'rambda'
20745
20746describe('R.tap', () => {
20747 it('happy', () => {
20748 pipe(
20749 tap(x => {
20750 x // $ExpectType number[]
20751 }),
20752 (x: number[]) => x.length
20753 )([1, 2])
20754 })
20755})
20756```
20757
20758</details>
20759
20760<details>
20761
20762<summary>2 failed <italic>Ramda.tap</italic> specs
20763
20764> :boom: Reason for the failure: Ramda method can act as a transducer
20765</summary>
20766
20767```javascript
20768var R = require('../../../../dist/rambda.js');
20769var eq = require('./shared/eq');
20770var listXf = require('./helpers/listXf');
20771var _curry2 = require('rambda/internal/_curry2');
20772
20773describe('tap', function() {
20774 var pushToList = _curry2(function(lst, x) { lst.push(x); });
20775 it('can act as a transducer', function() {
20776 var sideEffect = [];
20777 var numbers = [1,2,3,4,5];
20778 var xf = R.compose(R.map(R.identity), R.tap(pushToList(sideEffect)));
20779 eq(R.into([], xf, numbers), numbers);
20780 eq(sideEffect, numbers);
20781 });
20782 it('dispatches to transformer objects', function() {
20783 var sideEffect = [];
20784 var pushToSideEffect = pushToList(sideEffect);
20785 eq(R.tap(pushToSideEffect, listXf), {
20786 f: pushToSideEffect,
20787 xf: listXf
20788 });
20789 });
20790});
20791```
20792
20793</details>
20794
20795[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#tap)
20796
20797### test
20798
20799```typescript
20800
20801test(regExpression: RegExp): (str: string) => boolean
20802```
20803
20804It determines whether `str` matches `regExpression`.
20805
20806```javascript
20807R.test(/^f/, 'foo')
20808// => true
20809```
20810
20811<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.test(%2F%5Ef%2F%2C%20'foo')%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.test</strong> example in Rambda REPL</a>
20812
20813<details>
20814
20815<summary>All Typescript definitions</summary>
20816
20817```typescript
20818test(regExpression: RegExp): (str: string) => boolean;
20819test(regExpression: RegExp, str: string): boolean;
20820```
20821
20822</details>
20823
20824<details>
20825
20826<summary><strong>R.test</strong> source</summary>
20827
20828```javascript
20829export function test(pattern, str){
20830 if (arguments.length === 1) return _str => test(pattern, _str)
20831
20832 if (typeof pattern === 'string'){
20833 throw new TypeError(`‘test’ requires a value of type RegExp as its first argument; received "${ pattern }"`)
20834 }
20835
20836 return str.search(pattern) !== -1
20837}
20838```
20839
20840</details>
20841
20842<details>
20843
20844<summary><strong>Tests</strong></summary>
20845
20846```javascript
20847import { test as testMethod } from './test'
20848
20849test('happy', () => {
20850 expect(testMethod(/^x/, 'xyz')).toBeTrue()
20851
20852 expect(testMethod(/^y/)('xyz')).toBeFalse()
20853})
20854
20855test('throws if first argument is not regex', () => {
20856 expect(() => testMethod('foo', 'bar')).toThrowWithMessage(TypeError,
20857 '‘test’ requires a value of type RegExp as its first argument; received "foo"')
20858})
20859```
20860
20861</details>
20862
20863<details>
20864
20865<summary><strong>Typescript</strong> test</summary>
20866
20867```typescript
20868import {test} from 'rambda'
20869
20870const input = 'foo '
20871const regex = /foo/
20872
20873describe('R.test', () => {
20874 it('happy', () => {
20875 const result = test(regex, input)
20876
20877 result // $ExpectType boolean
20878 })
20879 it('curried', () => {
20880 const result = test(regex)(input)
20881
20882 result // $ExpectType boolean
20883 })
20884})
20885```
20886
20887</details>
20888
20889[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#test)
20890
20891### times
20892
20893```typescript
20894
20895times<T>(fn: (i: number) => T, howMany: number): T[]
20896```
20897
20898It returns the result of applying function `fn` over members of range array.
20899
20900The range array includes numbers between `0` and `howMany`(exclusive).
20901
20902```javascript
20903const fn = x => x * 2
20904const howMany = 5
20905
20906R.times(fn, howMany)
20907//=> [0, 2, 4, 6, 8]
20908```
20909
20910<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20fn%20%3D%20x%20%3D%3E%20x%20*%202%0Aconst%20howMany%20%3D%205%0A%0AR.times(fn%2C%20howMany)%0A%2F%2F%3D%3E%20%5B0%2C%202%2C%204%2C%206%2C%208%5D">Try this <strong>R.times</strong> example in Rambda REPL</a>
20911
20912<details>
20913
20914<summary>All Typescript definitions</summary>
20915
20916```typescript
20917times<T>(fn: (i: number) => T, howMany: number): T[];
20918times<T>(fn: (i: number) => T): (howMany: number) => T[];
20919```
20920
20921</details>
20922
20923<details>
20924
20925<summary><strong>R.times</strong> source</summary>
20926
20927```javascript
20928import { map } from './map'
20929import { range } from './range'
20930
20931export function times(fn, howMany){
20932 if (arguments.length === 1) return _howMany => times(fn, _howMany)
20933 if (!Number.isInteger(howMany) || howMany < 0){
20934 throw new RangeError('n must be an integer')
20935 }
20936
20937 return map(fn, range(0, howMany))
20938}
20939```
20940
20941</details>
20942
20943<details>
20944
20945<summary><strong>Tests</strong></summary>
20946
20947```javascript
20948import assert from 'assert'
20949
20950import { identity } from './identity'
20951import { times } from './times'
20952
20953test('happy', () => {
20954 const result = times(identity, 5)
20955
20956 expect(result).toEqual([ 0, 1, 2, 3, 4 ])
20957})
20958
20959test('with bad input', () => {
20960 assert.throws(() => {
20961 times(3)('cheers!')
20962 }, RangeError)
20963 assert.throws(() => {
20964 times(identity, -1)
20965 }, RangeError)
20966})
20967
20968test('curry', () => {
20969 const result = times(identity)(5)
20970
20971 expect(result).toEqual([ 0, 1, 2, 3, 4 ])
20972})
20973```
20974
20975</details>
20976
20977<details>
20978
20979<summary><strong>Typescript</strong> test</summary>
20980
20981```typescript
20982import {times, identity} from 'rambda'
20983
20984describe('R.times', () => {
20985 it('happy', () => {
20986 const result = times(identity, 5)
20987 result // $ExpectType number[]
20988 })
20989})
20990```
20991
20992</details>
20993
20994[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#times)
20995
20996### toLower
20997
20998```typescript
20999
21000toLower(str: string): string
21001```
21002
21003```javascript
21004R.toLower('FOO')
21005// => 'foo'
21006```
21007
21008<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.toLower('FOO')%0A%2F%2F%20%3D%3E%20'foo'">Try this <strong>R.toLower</strong> example in Rambda REPL</a>
21009
21010<details>
21011
21012<summary>All Typescript definitions</summary>
21013
21014```typescript
21015toLower(str: string): string;
21016```
21017
21018</details>
21019
21020<details>
21021
21022<summary><strong>R.toLower</strong> source</summary>
21023
21024```javascript
21025export function toLower(str){
21026 return str.toLowerCase()
21027}
21028```
21029
21030</details>
21031
21032<details>
21033
21034<summary><strong>Tests</strong></summary>
21035
21036```javascript
21037import { toLower } from './toLower'
21038
21039test('toLower', () => {
21040 expect(toLower('FOO|BAR|BAZ')).toEqual('foo|bar|baz')
21041})
21042```
21043
21044</details>
21045
21046[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#toLower)
21047
21048### toPairs
21049
21050```typescript
21051
21052toPairs<S>(obj: { [k: string]: S } | { [k: number]: S }): [string, S][]
21053```
21054
21055It transforms an object to a list.
21056
21057```javascript
21058const list = {
21059 a : 1,
21060 b : 2,
21061 c : [ 3, 4 ],
21062}
21063const expected = [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', [ 3, 4 ] ] ]
21064
21065const result = R.toPairs(list)
21066// => `result` is equal to `expected`
21067```
21068
21069<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%202%2C%0A%20%20c%20%3A%20%5B%203%2C%204%20%5D%2C%0A%7D%0Aconst%20expected%20%3D%20%5B%20%5B%20'a'%2C%201%20%5D%2C%20%5B%20'b'%2C%202%20%5D%2C%20%5B%20'c'%2C%20%5B%203%2C%204%20%5D%20%5D%20%5D%0A%0Aconst%20result%20%3D%20R.toPairs(list)%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.toPairs</strong> example in Rambda REPL</a>
21070
21071<details>
21072
21073<summary>All Typescript definitions</summary>
21074
21075```typescript
21076toPairs<S>(obj: { [k: string]: S } | { [k: number]: S }): [string, S][];
21077```
21078
21079</details>
21080
21081<details>
21082
21083<summary><strong>R.toPairs</strong> source</summary>
21084
21085```javascript
21086export function toPairs(obj){
21087 return Object.entries(obj)
21088}
21089```
21090
21091</details>
21092
21093<details>
21094
21095<summary><strong>Tests</strong></summary>
21096
21097```javascript
21098import { toPairs } from './toPairs'
21099
21100const obj = {
21101 a : 1,
21102 b : 2,
21103 c : [ 3, 4 ],
21104}
21105const expected = [
21106 [ 'a', 1 ],
21107 [ 'b', 2 ],
21108 [ 'c', [ 3, 4 ] ],
21109]
21110
21111test('happy', () => {
21112 expect(toPairs(obj)).toEqual(expected)
21113})
21114```
21115
21116</details>
21117
21118<details>
21119
21120<summary><strong>Typescript</strong> test</summary>
21121
21122```typescript
21123import {toPairs} from 'rambda'
21124
21125const obj = {
21126 a: 1,
21127 b: 2,
21128 c: [3, 4],
21129}
21130
21131describe('R.toPairs', () => {
21132 it('happy', () => {
21133 const result = toPairs(obj)
21134
21135 result // $ExpectType [string, number | number[]][]
21136 })
21137})
21138```
21139
21140</details>
21141
21142[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#toPairs)
21143
21144### toString
21145
21146```typescript
21147
21148toString<T>(x: T): string
21149```
21150
21151```javascript
21152R.toString([1, 2])
21153// => '1,2'
21154```
21155
21156<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.toString(%5B1%2C%202%5D)%20%0A%2F%2F%20%3D%3E%20'1%2C2'">Try this <strong>R.toString</strong> example in Rambda REPL</a>
21157
21158<details>
21159
21160<summary>All Typescript definitions</summary>
21161
21162```typescript
21163toString<T>(x: T): string;
21164```
21165
21166</details>
21167
21168<details>
21169
21170<summary><strong>R.toString</strong> source</summary>
21171
21172```javascript
21173export function toString(x){
21174 return x.toString()
21175}
21176```
21177
21178</details>
21179
21180<details>
21181
21182<summary><strong>Tests</strong></summary>
21183
21184```javascript
21185import { toString } from './toString'
21186
21187test('happy', () => {
21188 expect(toString([ 1, 2, 3 ])).toEqual('1,2,3')
21189})
21190```
21191
21192</details>
21193
21194[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#toString)
21195
21196### toUpper
21197
21198```typescript
21199
21200toUpper(str: string): string
21201```
21202
21203```javascript
21204R.toUpper('foo')
21205// => 'FOO'
21206```
21207
21208<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.toUpper('foo')%0A%2F%2F%20%3D%3E%20'FOO'">Try this <strong>R.toUpper</strong> example in Rambda REPL</a>
21209
21210<details>
21211
21212<summary>All Typescript definitions</summary>
21213
21214```typescript
21215toUpper(str: string): string;
21216```
21217
21218</details>
21219
21220<details>
21221
21222<summary><strong>R.toUpper</strong> source</summary>
21223
21224```javascript
21225export function toUpper(str){
21226 return str.toUpperCase()
21227}
21228```
21229
21230</details>
21231
21232<details>
21233
21234<summary><strong>Tests</strong></summary>
21235
21236```javascript
21237import { toUpper } from './toUpper'
21238
21239test('toUpper', () => {
21240 expect(toUpper('foo|bar|baz')).toEqual('FOO|BAR|BAZ')
21241})
21242```
21243
21244</details>
21245
21246[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#toUpper)
21247
21248### transpose
21249
21250```typescript
21251
21252transpose<T>(list: readonly T[][]): T[][]
21253```
21254
21255```javascript
21256const list = [[10, 11], [20], [], [30, 31, 32]]
21257const expected = [[10, 20, 30], [11, 31], [32]]
21258
21259const result = R.transpose(list)
21260// => `result` is equal to `expected`
21261```
21262
21263<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%5B10%2C%2011%5D%2C%20%5B20%5D%2C%20%5B%5D%2C%20%5B30%2C%2031%2C%2032%5D%5D%0Aconst%20expected%20%3D%20%5B%5B10%2C%2020%2C%2030%5D%2C%20%5B11%2C%2031%5D%2C%20%5B32%5D%5D%0A%0Aconst%20result%20%3D%20R.transpose(list)%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.transpose</strong> example in Rambda REPL</a>
21264
21265<details>
21266
21267<summary>All Typescript definitions</summary>
21268
21269```typescript
21270transpose<T>(list: readonly T[][]): T[][];
21271```
21272
21273</details>
21274
21275<details>
21276
21277<summary><strong>R.transpose</strong> source</summary>
21278
21279```javascript
21280import { _isArray } from './_internals/_isArray'
21281
21282export function transpose(array){
21283 return array.reduce((acc, el) => {
21284 el.forEach((nestedEl, i) =>
21285 _isArray(acc[ i ]) ? acc[ i ].push(nestedEl) : acc.push([ nestedEl ]))
21286
21287 return acc
21288 }, [])
21289}
21290```
21291
21292</details>
21293
21294<details>
21295
21296<summary><strong>Tests</strong></summary>
21297
21298```javascript
21299import { transpose } from './transpose'
21300
21301test('happy', () => {
21302 const input = [
21303 [ 'a', 1 ],
21304 [ 'b', 2 ],
21305 [ 'c', 3 ],
21306 ]
21307
21308 expect(transpose(input)).toEqual([
21309 [ 'a', 'b', 'c' ],
21310 [ 1, 2, 3 ],
21311 ])
21312})
21313
21314test('when rows are shorter', () => {
21315 const actual = transpose([ [ 10, 11 ], [ 20 ], [], [ 30, 31, 32 ] ])
21316 const expected = [ [ 10, 20, 30 ], [ 11, 31 ], [ 32 ] ]
21317 expect(actual).toEqual(expected)
21318})
21319
21320test('with empty array', () => {
21321 expect(transpose([])).toEqual([])
21322})
21323
21324test('array with falsy values', () => {
21325 const actual = transpose([
21326 [ true, false, undefined, null ],
21327 [ null, undefined, false, true ],
21328 ])
21329 const expected = [
21330 [ true, null ],
21331 [ false, undefined ],
21332 [ undefined, false ],
21333 [ null, true ],
21334 ]
21335 expect(actual).toEqual(expected)
21336})
21337```
21338
21339</details>
21340
21341<details>
21342
21343<summary><strong>Typescript</strong> test</summary>
21344
21345```typescript
21346import {transpose} from 'rambda'
21347
21348const input = [
21349 ['a', 1],
21350 ['b', 2],
21351 ['c', 3],
21352]
21353
21354describe('R.transpose', () => {
21355 it('happy', () => {
21356 const result = transpose(input)
21357
21358 result // $ExpectType (string | number)[][]
21359 })
21360})
21361```
21362
21363</details>
21364
21365[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#transpose)
21366
21367### trim
21368
21369```typescript
21370
21371trim(str: string): string
21372```
21373
21374```javascript
21375R.trim(' foo ')
21376// => 'foo'
21377```
21378
21379<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.trim('%20%20foo%20%20')%20%0A%2F%2F%20%3D%3E%20'foo'">Try this <strong>R.trim</strong> example in Rambda REPL</a>
21380
21381<details>
21382
21383<summary>All Typescript definitions</summary>
21384
21385```typescript
21386trim(str: string): string;
21387```
21388
21389</details>
21390
21391<details>
21392
21393<summary><strong>R.trim</strong> source</summary>
21394
21395```javascript
21396export function trim(str){
21397 return str.trim()
21398}
21399```
21400
21401</details>
21402
21403<details>
21404
21405<summary><strong>Tests</strong></summary>
21406
21407```javascript
21408import { trim } from './trim'
21409
21410test('trim', () => {
21411 expect(trim(' foo ')).toEqual('foo')
21412})
21413```
21414
21415</details>
21416
21417<details>
21418
21419<summary>1 failed <italic>Ramda.trim</italic> specs
21420
21421> :boom: Reason for the failure: Ramda method trims all ES5 whitespace
21422</summary>
21423
21424```javascript
21425var R = require('../../../../dist/rambda.js');
21426var eq = require('./shared/eq');
21427
21428describe('trim', function() {
21429 var test = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFFHello, World!\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
21430 it('trims all ES5 whitespace', function() {
21431 eq(R.trim(test), 'Hello, World!');
21432 eq(R.trim(test).length, 13);
21433 });
21434 if (typeof String.prototype.trim !== 'function') {
21435 it('falls back to a shim if String.prototype.trim is not present', function() {
21436 eq(R.trim(' xyz '), 'xyz');
21437 eq(R.trim(test), 'Hello, World!');
21438 eq(R.trim(test).length, 13);
21439 eq(R.trim('\u200b'), '\u200b');
21440 eq(R.trim('\u200b').length, 1);
21441 });
21442 }
21443});
21444```
21445
21446</details>
21447
21448[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#trim)
21449
21450### tryCatch
21451
21452```typescript
21453
21454tryCatch<T, U>(
21455 fn: (input: T) => U,
21456 fallback: U
21457): (input: T) => U
21458```
21459
21460It returns function that runs `fn` in `try/catch` block. If there was an error, then `fallback` is used to return the result. Note that `fn` can be value or asynchronous/synchronous function(unlike `Ramda` where fallback can only be a synchronous function).
21461
21462> :boom: Please check the tests of `R.tryCatch` to fully understand how this method works.
21463
21464```javascript
21465const fn = x => x.foo
21466
21467const result = [
21468 R.tryCatch(fn, false)(null),
21469 R.tryCatch(fn, false)({foo: 'bar'})
21470]
21471// => [false, 'bar']
21472```
21473
21474<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20x%20%3D%3E%20x.foo%0A%0Aconst%20result%20%3D%20%5B%0A%20%20R.tryCatch(fn%2C%20false)(null)%2C%0A%20%20R.tryCatch(fn%2C%20false)(%7Bfoo%3A%20'bar'%7D)%0A%5D%0A%2F%2F%20%3D%3E%20%5Bfalse%2C%20'bar'%5D">Try this <strong>R.tryCatch</strong> example in Rambda REPL</a>
21475
21476<details>
21477
21478<summary>All Typescript definitions</summary>
21479
21480```typescript
21481tryCatch<T, U>(
21482 fn: (input: T) => U,
21483 fallback: U
21484): (input: T) => U;
21485tryCatch<T, U>(
21486 fn: (input: T) => U,
21487 fallback: (input: T) => U
21488): (input: T) => U;
21489tryCatch<T>(
21490 fn: (input: any) => Promise<any>,
21491 fallback: T
21492): (input: any) => Promise<T>;
21493tryCatch<T>(
21494 fn: (input: any) => Promise<any>,
21495 fallback: (input: any) => Promise<any>,
21496): (input: any) => Promise<T>;
21497```
21498
21499</details>
21500
21501<details>
21502
21503<summary><strong>R.tryCatch</strong> source</summary>
21504
21505```javascript
21506import { isFunction } from './isFunction'
21507import { isPromise } from './isPromise'
21508
21509export function tryCatch(fn, fallback){
21510 if (!isFunction(fn)){
21511 throw new Error(`R.tryCatch | fn '${ fn }'`)
21512 }
21513 const passFallback = isFunction(fallback)
21514
21515 if (!isPromise(fn)){
21516 return (...inputs) => {
21517 try {
21518 return fn(...inputs)
21519 } catch (e){
21520 return passFallback ? fallback(e, ...inputs) : fallback
21521 }
21522 }
21523 }
21524
21525 return (...inputs) =>
21526 new Promise(resolve => {
21527 fn(...inputs)
21528 .then(resolve)
21529 .catch(() => {
21530 if (!passFallback){
21531 return resolve(fallback)
21532 }
21533
21534 if (!isPromise(fallback)){
21535 return resolve(fallback(...inputs))
21536 }
21537
21538 fallback(...inputs).then(resolve)
21539 })
21540 })
21541}
21542```
21543
21544</details>
21545
21546<details>
21547
21548<summary><strong>Tests</strong></summary>
21549
21550```javascript
21551import { delay } from './delay'
21552import { prop } from './prop'
21553import { tryCatch } from './tryCatch'
21554
21555test('throws when fn is not function', () => {
21556 const fn = 'foo'
21557
21558 expect(() => tryCatch(fn, false)(null)).toThrowWithMessage(Error,
21559 'R.tryCatch | fn \'foo\'')
21560})
21561
21562test('when fallback is used', () => {
21563 const fn = x => x.x
21564
21565 expect(tryCatch(fn, false)(null)).toBeFalse()
21566})
21567
21568test('with json parse', () => {
21569 const good = () => JSON.parse(JSON.stringify({ a : 1 }))
21570 const bad = () => JSON.parse('a{a')
21571
21572 expect(tryCatch(good, 1)(null)).toEqual({ a : 1 })
21573 expect(tryCatch(bad, 1)(null)).toBe(1)
21574})
21575
21576test('when fallback is function', () => {
21577 const fn = x => x.x
21578
21579 expect(tryCatch(fn, () => 1)(null)).toBe(1)
21580})
21581
21582test('when fn is used', () => {
21583 const fn = prop('x')
21584
21585 expect(tryCatch(fn, false)({})).toBe(undefined)
21586 expect(tryCatch(fn, false)({ x : 1 })).toBe(1)
21587})
21588
21589test('fallback receives error object and all initial inputs', () => {
21590 function thrower(
21591 a, b, c
21592 ){
21593 void c
21594 throw new Error('throwerError')
21595 }
21596
21597 function catchFn(
21598 e, a, b, c
21599 ){
21600 return [ e.message, a, b, c ].join('|')
21601 }
21602
21603 const willThrow = tryCatch(thrower, catchFn)
21604 const result = willThrow(
21605 'A', 'B', 'C'
21606 )
21607 expect(result).toBe('throwerError|A|B|C')
21608})
21609
21610test('fallback receives error object', () => {
21611 function throwFn(){
21612 throw new Error(10)
21613 }
21614
21615 function eCatcher(
21616 e, a, b
21617 ){
21618 return e.message
21619 }
21620
21621 const willThrow = tryCatch(throwFn, eCatcher)
21622 expect(willThrow([])).toBe('10')
21623 expect(willThrow([ {}, {}, {} ])).toBe('10')
21624})
21625
21626test('when async + fallback', async () => {
21627 let called = false
21628
21629 const fn = async input => {
21630 await delay(input)
21631 called = true
21632
21633 return JSON.parse('{a:')
21634 }
21635
21636 expect(await tryCatch(fn, 'fallback')(100)).toBe('fallback')
21637 expect(called).toBeTrue()
21638})
21639
21640test('when async + fallback is function', async () => {
21641 let called = false
21642
21643 const fn = async input => {
21644 await delay(input)
21645 called = true
21646
21647 return JSON.parse('{a:')
21648 }
21649
21650 expect(await tryCatch(fn, x => x + 1)(100)).toBe(101)
21651 expect(called).toBeTrue()
21652})
21653
21654test('when async + fallback is async', async () => {
21655 let called = false
21656 const fn = async input => {
21657 await delay(input)
21658 called = true
21659
21660 return JSON.parse('{a:')
21661 }
21662 const fallback = async input => {
21663 await delay(10)
21664
21665 return input + 1
21666 }
21667
21668 expect(await tryCatch(fn, fallback)(100)).toBe(101)
21669 expect(called).toBeTrue()
21670})
21671
21672test('when async + fn', async () => {
21673 let called = false
21674
21675 const fn = async input => {
21676 await delay(input)
21677 called = true
21678
21679 return input + 1
21680 }
21681
21682 expect(await tryCatch(fn, 'fallback')(100)).toBe(101)
21683 expect(called).toBeTrue()
21684})
21685```
21686
21687</details>
21688
21689<details>
21690
21691<summary><strong>Typescript</strong> test</summary>
21692
21693```typescript
21694import {tryCatch, delay} from 'rambda'
21695
21696describe('R.tryCatch', () => {
21697 it('synchronous', () => {
21698 const fn = (x: any) => x.x === 1
21699
21700 const result = tryCatch(fn, false)(null)
21701 result // $ExpectType boolean
21702 })
21703 it('synchronous + fallback is function', () => {
21704 const fn = (x: any) => typeof x.x
21705 const fallback = (x: any) => typeof x
21706 const result = tryCatch<any, string>(fn, fallback)(null)
21707 result // $ExpectType string
21708 })
21709
21710 it('asynchronous', async() => {
21711 const fn = async(input: any) => {
21712 return typeof JSON.parse('{a:')
21713 }
21714 const result = await tryCatch<string>(fn, 'fallback')(100)
21715 result // $ExpectType string
21716 })
21717
21718 it('asynchronous + fallback is asynchronous', async() => {
21719 const fn = async(input: any) => {
21720 await delay(100)
21721 return JSON.parse(`{a:${input}`)
21722 }
21723 const fallback = async(input: any) => {
21724 await delay(100)
21725 return 'foo'
21726 }
21727 const result = await tryCatch<string>(fn, fallback)(100)
21728 result // $ExpectType string
21729 })
21730})
21731```
21732
21733</details>
21734
21735*1 failed Ramda.tryCatch specs*
21736
21737> :boom: Reason for the failure: Ramda method returns a function with the same arity
21738
21739[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#tryCatch)
21740
21741### type
21742
21743```typescript
21744
21745type(x: any): "Object" | "Number" | "Boolean" | "String" | "Null" | "Array" | "Function" | "Undefined" | "Async" | "Promise" | "RegExp" | "NaN"
21746```
21747
21748It accepts any input and it returns its type.
21749
21750> :boom: `NaN`, `Promise` and `Async` are types specific for **Rambda**.
21751
21752```javascript
21753R.type(() => {}) // => 'Function'
21754R.type(async () => {}) // => 'Async'
21755R.type([]) // => 'Array'
21756R.type({}) // => 'Object'
21757R.type('foo') // => 'String'
21758R.type(1) // => 'Number'
21759R.type(true) // => 'Boolean'
21760R.type(null) // => 'Null'
21761R.type(/[A-z]/) // => 'RegExp'
21762R.type('foo'*1) // => 'NaN'
21763
21764const delay = ms => new Promise(resolve => {
21765 setTimeout(function () {
21766 resolve()
21767 }, ms)
21768})
21769R.type(delay) // => 'Promise'
21770```
21771
21772<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.type(()%20%3D%3E%20%7B%7D)%20%2F%2F%20%3D%3E%20'Function'%0AR.type(async%20()%20%3D%3E%20%7B%7D)%20%2F%2F%20%3D%3E%20'Async'%0AR.type(%5B%5D)%20%2F%2F%20%3D%3E%20'Array'%0AR.type(%7B%7D)%20%2F%2F%20%3D%3E%20'Object'%0AR.type('foo')%20%2F%2F%20%3D%3E%20'String'%0AR.type(1)%20%2F%2F%20%3D%3E%20'Number'%0AR.type(true)%20%2F%2F%20%3D%3E%20'Boolean'%0AR.type(null)%20%2F%2F%20%3D%3E%20'Null'%0AR.type(%2F%5BA-z%5D%2F)%20%2F%2F%20%3D%3E%20'RegExp'%0AR.type('foo'*1)%20%2F%2F%20%3D%3E%20'NaN'%0A%0Aconst%20delay%20%3D%20ms%20%3D%3E%20new%20Promise(resolve%20%3D%3E%20%7B%0A%20%20setTimeout(function%20()%20%7B%0A%20%20%20%20resolve()%0A%20%20%7D%2C%20ms)%0A%7D)%0AR.type(delay)%20%2F%2F%20%3D%3E%20'Promise'">Try this <strong>R.type</strong> example in Rambda REPL</a>
21773
21774<details>
21775
21776<summary>All Typescript definitions</summary>
21777
21778```typescript
21779type(x: any): "Object" | "Number" | "Boolean" | "String" | "Null" | "Array" | "Function" | "Undefined" | "Async" | "Promise" | "RegExp" | "NaN";
21780```
21781
21782</details>
21783
21784<details>
21785
21786<summary><strong>R.type</strong> source</summary>
21787
21788```javascript
21789import { _isArray } from './_internals/_isArray'
21790
21791export function type(input){
21792 const typeOf = typeof input
21793
21794 if (input === null){
21795 return 'Null'
21796 } else if (input === undefined){
21797 return 'Undefined'
21798 } else if (typeOf === 'boolean'){
21799 return 'Boolean'
21800 } else if (typeOf === 'number'){
21801 return Number.isNaN(input) ? 'NaN' : 'Number'
21802 } else if (typeOf === 'string'){
21803 return 'String'
21804 } else if (_isArray(input)){
21805 return 'Array'
21806 } else if (input instanceof RegExp){
21807 return 'RegExp'
21808 }
21809
21810 const asStr = input && input.toString ? input.toString() : ''
21811
21812 if ([ 'true', 'false' ].includes(asStr)) return 'Boolean'
21813 if (!Number.isNaN(Number(asStr))) return 'Number'
21814 if (asStr.startsWith('async')) return 'Async'
21815 if (asStr === '[object Promise]') return 'Promise'
21816 if (typeOf === 'function') return 'Function'
21817 if (input instanceof String) return 'String'
21818
21819 return 'Object'
21820}
21821```
21822
21823</details>
21824
21825<details>
21826
21827<summary><strong>Tests</strong></summary>
21828
21829```javascript
21830import { type as ramdaType } from 'ramda'
21831
21832import { type } from './type'
21833
21834test('with simple promise', () => {
21835 expect(type(Promise.resolve(1))).toBe('Promise')
21836})
21837
21838test('with new Boolean', () => {
21839 expect(type(new Boolean(true))).toBe('Boolean')
21840})
21841
21842test('with new String', () => {
21843 expect(type(new String('I am a String object'))).toEqual('String')
21844})
21845
21846test('with new Number', () => {
21847 expect(type(new Number(1))).toBe('Number')
21848})
21849
21850test('with new promise', () => {
21851 const delay = ms =>
21852 new Promise(resolve => {
21853 setTimeout(() => {
21854 resolve(ms + 110)
21855 }, ms)
21856 })
21857
21858 expect(type(delay(10))).toEqual('Promise')
21859})
21860
21861test('async function', () => {
21862 expect(type(async () => {})).toEqual('Async')
21863})
21864
21865test('async arrow', () => {
21866 const asyncArrow = async () => {}
21867 expect(type(asyncArrow)).toBe('Async')
21868})
21869
21870test('function', () => {
21871 const fn1 = () => {}
21872 const fn2 = function (){}
21873
21874 function fn3(){}
21875
21876 ;[ () => {}, fn1, fn2, fn3 ].map(val => {
21877 expect(type(val)).toEqual('Function')
21878 })
21879})
21880
21881test('object', () => {
21882 expect(type({})).toEqual('Object')
21883})
21884
21885test('number', () => {
21886 expect(type(1)).toEqual('Number')
21887})
21888
21889test('boolean', () => {
21890 expect(type(false)).toEqual('Boolean')
21891})
21892
21893test('string', () => {
21894 expect(type('foo')).toEqual('String')
21895})
21896
21897test('null', () => {
21898 expect(type(null)).toEqual('Null')
21899})
21900
21901test('array', () => {
21902 expect(type([])).toEqual('Array')
21903 expect(type([ 1, 2, 3 ])).toEqual('Array')
21904})
21905
21906test('regex', () => {
21907 expect(type(/\s/g)).toEqual('RegExp')
21908})
21909
21910test('undefined', () => {
21911 expect(type(undefined)).toEqual('Undefined')
21912})
21913
21914test('not a number', () => {
21915 expect(type(Number('s'))).toBe('NaN')
21916})
21917
21918test('function inside object 1', () => {
21919 const obj = {
21920 f(){
21921 return 4
21922 },
21923 }
21924
21925 expect(type(obj.f)).toBe('Function')
21926 expect(ramdaType(obj.f)).toBe('Function')
21927})
21928
21929test('function inside object 2', () => {
21930 const name = 'f'
21931 const obj = {
21932 [ name ](){
21933 return 4
21934 },
21935 }
21936 expect(type(obj.f)).toBe('Function')
21937 expect(ramdaType(obj.f)).toBe('Function')
21938})
21939```
21940
21941</details>
21942
21943<details>
21944
21945<summary><strong>Typescript</strong> test</summary>
21946
21947```typescript
21948import {type} from 'rambda'
21949
21950describe('R.type', () => {
21951 it('happy', () => {
21952 const result = type(4)
21953
21954 result // $ExpectType RambdaTypes
21955 })
21956})
21957```
21958
21959</details>
21960
21961<details>
21962
21963<summary>1 failed <italic>Ramda.type</italic> specs
21964
21965> :boom: Reason for the failure: Ramda method returns 'Number' type to NaN input, while Rambda method returns 'NaN'
21966</summary>
21967
21968```javascript
21969var R = require('../../../../dist/rambda.js');
21970var eq = require('./shared/eq');
21971
21972describe('type', function() {
21973 // it('"Arguments" if given an arguments object', function() {
21974 // var args = (function() { return arguments; }());
21975 // eq(R.type(args), 'Arguments');
21976 // });
21977 it('"Number" if given the NaN value', function() {
21978 eq(R.type(NaN), 'Number');
21979 });
21980});
21981```
21982
21983</details>
21984
21985[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#type)
21986
21987### union
21988
21989```typescript
21990
21991union<T>(x: readonly T[], y: readonly T[]): T[]
21992```
21993
21994It takes two lists and return a new list containing a merger of both list with removed duplicates.
21995
21996`R.equals` is used to compare for duplication, which means that it can be safely used with array of objects.
21997
21998```javascript
21999const result = R.union([1,2,3], [3,4,5]);
22000//=> [1, 2, 3, 4, 5]
22001```
22002
22003<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20R.union(%5B1%2C2%2C3%5D%2C%20%5B3%2C4%2C5%5D)%3B%0A%2F%2F%3D%3E%20%5B1%2C%202%2C%203%2C%204%2C%205%5D">Try this <strong>R.union</strong> example in Rambda REPL</a>
22004
22005<details>
22006
22007<summary>All Typescript definitions</summary>
22008
22009```typescript
22010union<T>(x: readonly T[], y: readonly T[]): T[];
22011union<T>(x: readonly T[]): (y: readonly T[]) => T[];
22012```
22013
22014</details>
22015
22016<details>
22017
22018<summary><strong>R.union</strong> source</summary>
22019
22020```javascript
22021import { includes } from './includes'
22022
22023export function union(x, y){
22024 if (arguments.length === 1) return _y => union(x, _y)
22025
22026 const toReturn = x.slice()
22027
22028 y.forEach(yInstance => {
22029 if (!includes(yInstance, x)) toReturn.push(yInstance)
22030 })
22031
22032 return toReturn
22033}
22034```
22035
22036</details>
22037
22038<details>
22039
22040<summary><strong>Tests</strong></summary>
22041
22042```javascript
22043import { union } from './union'
22044
22045test('happy', () => {
22046 expect(union([ 1, 2 ], [ 2, 3 ])).toEqual([ 1, 2, 3 ])
22047})
22048
22049test('with list of objects', () => {
22050 const list1 = [ { a : 1 }, { a : 2 } ]
22051 const list2 = [ { a : 2 }, { a : 3 } ]
22052 const result = union(list1)(list2)
22053})
22054```
22055
22056</details>
22057
22058<details>
22059
22060<summary><strong>Typescript</strong> test</summary>
22061
22062```typescript
22063import {union} from 'rambda'
22064
22065describe('R.union', () => {
22066 it('happy', () => {
22067 const result = union([1, 2], [2, 3])
22068
22069 result // $ExpectType number[]
22070 })
22071 it('with array of objects - case 1', () => {
22072 const list1 = [{a: 1}, {a: 2}]
22073 const list2 = [{a: 2}, {a: 3}]
22074 const result = union(list1, list2)
22075 result // $ExpectType { a: number; }[]
22076 })
22077 it('with array of objects - case 2', () => {
22078 const list1 = [{a: 1, b: 1}, {a: 2}]
22079 const list2 = [{a: 2}, {a: 3, b: 3}]
22080 const result = union(list1, list2)
22081 result[0].a // $ExpectType number
22082 result[0].b // $ExpectType number | undefined
22083 })
22084})
22085
22086describe('R.union - curried', () => {
22087 it('happy', () => {
22088 const result = union([1, 2])([2, 3])
22089
22090 result // $ExpectType number[]
22091 })
22092 it('with array of objects - case 1', () => {
22093 const list1 = [{a: 1}, {a: 2}]
22094 const list2 = [{a: 2}, {a: 3}]
22095 const result = union(list1)(list2)
22096 result // $ExpectType { a: number; }[]
22097 })
22098 it('with array of objects - case 2', () => {
22099 const list1 = [{a: 1, b: 1}, {a: 2}]
22100 const list2 = [{a: 2}, {a: 3, b: 3}]
22101 const result = union(list1)(list2)
22102 result[0].a // $ExpectType number
22103 result[0].b // $ExpectType number | undefined
22104 })
22105})
22106```
22107
22108</details>
22109
22110*1 failed Ramda.union specs*
22111
22112> :boom: Reason for the failure: Ramda library supports fantasy-land
22113
22114[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#union)
22115
22116### uniq
22117
22118```typescript
22119
22120uniq<T>(list: readonly T[]): T[]
22121```
22122
22123It returns a new array containing only one copy of each element of `list`.
22124
22125> :boom: `R.equals` is used to determine equality
22126
22127```javascript
22128const list = [1, 1, {a: 1}, {a: 2}, {a:1}]
22129
22130R.uniq(list)
22131// => [1, {a: 1}, {a: 2}]
22132```
22133
22134<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20list%20%3D%20%5B1%2C%201%2C%20%7Ba%3A%201%7D%2C%20%7Ba%3A%202%7D%2C%20%7Ba%3A1%7D%5D%0A%0AR.uniq(list)%0A%2F%2F%20%3D%3E%20%5B1%2C%20%7Ba%3A%201%7D%2C%20%7Ba%3A%202%7D%5D">Try this <strong>R.uniq</strong> example in Rambda REPL</a>
22135
22136<details>
22137
22138<summary>All Typescript definitions</summary>
22139
22140```typescript
22141uniq<T>(list: readonly T[]): T[];
22142```
22143
22144</details>
22145
22146<details>
22147
22148<summary><strong>R.uniq</strong> source</summary>
22149
22150```javascript
22151import { includes } from './includes'
22152
22153export function uniq(list){
22154 let index = -1
22155 const willReturn = []
22156
22157 while (++index < list.length){
22158 const value = list[ index ]
22159
22160 if (!includes(value, willReturn)){
22161 willReturn.push(value)
22162 }
22163 }
22164
22165 return willReturn
22166}
22167```
22168
22169</details>
22170
22171<details>
22172
22173<summary><strong>Tests</strong></summary>
22174
22175```javascript
22176import { uniq } from './uniq'
22177
22178test('uniq', () => {
22179 expect(uniq([ 1, 2, 3, 3, 3, 1, 2, 0 ])).toEqual([ 1, 2, 3, 0 ])
22180 expect(uniq([ 1, 1, 2, 1 ])).toEqual([ 1, 2 ])
22181 expect([ 1, '1' ]).toEqual([ 1, '1' ])
22182 expect(uniq([ [ 42 ], [ 42 ] ])).toEqual([ [ 42 ] ])
22183})
22184```
22185
22186</details>
22187
22188<details>
22189
22190<summary><strong>Typescript</strong> test</summary>
22191
22192```typescript
22193import {uniq} from 'rambda'
22194
22195describe('R.uniq', () => {
22196 it('happy', () => {
22197 const result = uniq([1, 2, 3, 3, 3, 1, 2, 0])
22198 result // $ExpectType number[]
22199 })
22200})
22201```
22202
22203</details>
22204
22205<details>
22206
22207<summary>2 failed <italic>Ramda.uniq</italic> specs
22208
22209> :boom: Reason for the failure: Ramda method pass to `uniq` method | Ramda method uses reference equality for functions
22210</summary>
22211
22212```javascript
22213var R = require('../../../../dist/rambda.js');
22214var eq = require('./shared/eq');
22215
22216describe('uniq', function() {
22217 it('has R.equals semantics', function() {
22218 function Just(x) { this.value = x; }
22219 Just.prototype.equals = function(x) {
22220 return x instanceof Just && R.equals(x.value, this.value);
22221 };
22222 eq(R.uniq([-0, -0]).length, 1);
22223 eq(R.uniq([0, -0]).length, 2);
22224 eq(R.uniq([NaN, NaN]).length, 1);
22225 eq(R.uniq([[1], [1]]).length, 1);
22226 eq(R.uniq([new Just([42]), new Just([42])]).length, 1);
22227 it('handles null and undefined elements', function() {
22228 eq(R.uniq([void 0, null, void 0, null]), [void 0, null]);
22229 it('uses reference equality for functions', function() {
22230 eq(R.uniq([R.add, R.identity, R.add, R.identity, R.add, R.identity]).length, 2);
22231});
22232```
22233
22234</details>
22235
22236[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#uniq)
22237
22238### uniqWith
22239
22240```typescript
22241
22242uniqWith<T, U>(uniqFn: (x: T, y: T) => boolean, list: readonly T[]): T[]
22243```
22244
22245It returns a new array containing only one copy of each element in `list` according to boolean returning function `uniqFn`.
22246
22247```javascript
22248const list = [
22249 {id: 0, title:'foo'},
22250 {id: 1, title:'bar'},
22251 {id: 2, title:'baz'},
22252 {id: 3, title:'foo'},
22253 {id: 4, title:'bar'},
22254]
22255
22256const expected = [
22257 {id: 0, title:'foo'},
22258 {id: 1, title:'bar'},
22259 {id: 2, title:'baz'},
22260]
22261
22262const uniqFn = (x,y) => x.title === y.title
22263
22264const result = R.uniqWith(uniqFn, list)
22265// => `result` is equal to `expected`
22266```
22267
22268<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list%20%3D%20%5B%0A%20%20%7Bid%3A%200%2C%20title%3A'foo'%7D%2C%0A%20%20%7Bid%3A%201%2C%20title%3A'bar'%7D%2C%0A%20%20%7Bid%3A%202%2C%20title%3A'baz'%7D%2C%0A%20%20%7Bid%3A%203%2C%20title%3A'foo'%7D%2C%0A%20%20%7Bid%3A%204%2C%20title%3A'bar'%7D%2C%0A%5D%0A%0Aconst%20expected%20%3D%20%5B%0A%20%20%7Bid%3A%200%2C%20title%3A'foo'%7D%2C%0A%20%20%7Bid%3A%201%2C%20title%3A'bar'%7D%2C%0A%20%20%7Bid%3A%202%2C%20title%3A'baz'%7D%2C%0A%5D%0A%0Aconst%20uniqFn%20%3D%20(x%2Cy)%20%3D%3E%20x.title%20%3D%3D%3D%20y.title%0A%0Aconst%20result%20%3D%20R.uniqWith(uniqFn%2C%20list)%0A%2F%2F%20%3D%3E%20%60result%60%20is%20equal%20to%20%60expected%60">Try this <strong>R.uniqWith</strong> example in Rambda REPL</a>
22269
22270<details>
22271
22272<summary>All Typescript definitions</summary>
22273
22274```typescript
22275uniqWith<T, U>(uniqFn: (x: T, y: T) => boolean, list: readonly T[]): T[];
22276uniqWith<T, U>(uniqFn: (x: T, y: T) => boolean): (list: readonly T[]) => T[];
22277```
22278
22279</details>
22280
22281<details>
22282
22283<summary><strong>R.uniqWith</strong> source</summary>
22284
22285```javascript
22286import { any } from './any'
22287
22288export function uniqWith(fn, list){
22289 if (arguments.length === 1) return _list => uniqWith(fn, _list)
22290
22291 let index = -1
22292 const len = list.length
22293 const willReturn = []
22294
22295 while (++index < len){
22296 const value = list[ index ]
22297 const flag = any(willReturnInstance => fn(value, willReturnInstance),
22298 willReturn)
22299
22300 if (!flag){
22301 willReturn.push(value)
22302 }
22303 }
22304
22305 return willReturn
22306}
22307```
22308
22309</details>
22310
22311<details>
22312
22313<summary><strong>Tests</strong></summary>
22314
22315```javascript
22316import { uniqWith } from './uniqWith'
22317
22318test('happy', () => {
22319 const input = [
22320 {
22321 id : 0,
22322 title : 'foo',
22323 },
22324 {
22325 id : 1,
22326 title : 'bar',
22327 },
22328 {
22329 id : 2,
22330 title : 'baz',
22331 },
22332 {
22333 id : 3,
22334 title : 'foo',
22335 },
22336 {
22337 id : 4,
22338 title : 'bar',
22339 },
22340 ]
22341
22342 const expectedResult = [
22343 {
22344 id : 0,
22345 title : 'foo',
22346 },
22347 {
22348 id : 1,
22349 title : 'bar',
22350 },
22351 {
22352 id : 2,
22353 title : 'baz',
22354 },
22355 ]
22356
22357 const fn = (x, y) => x.title === y.title
22358
22359 const result = uniqWith(fn, input)
22360 const curriedResult = uniqWith(fn)(input)
22361
22362 expect(result).toEqual(expectedResult)
22363
22364 expect(curriedResult).toEqual(expectedResult)
22365})
22366
22367test('uniqWith', () => {
22368 const input = [
22369 {
22370 id : 0,
22371 title : 'foo',
22372 },
22373 {
22374 id : 1,
22375 title : 'bar',
22376 },
22377 {
22378 id : 2,
22379 title : 'baz',
22380 },
22381 {
22382 id : 3,
22383 title : 'foo',
22384 },
22385 {
22386 id : 4,
22387 title : 'bar',
22388 },
22389 ]
22390
22391 const expectedResult = [
22392 {
22393 id : 0,
22394 title : 'foo',
22395 },
22396 {
22397 id : 1,
22398 title : 'bar',
22399 },
22400 {
22401 id : 2,
22402 title : 'baz',
22403 },
22404 ]
22405
22406 const fn = (x, y) => x.title === y.title
22407
22408 const result = uniqWith(fn, input)
22409 //const result = uniqWith(Ramda.eqBy(Ramda.prop('title')), input)
22410
22411 expect(result).toEqual(expectedResult)
22412})
22413```
22414
22415</details>
22416
22417<details>
22418
22419<summary><strong>Typescript</strong> test</summary>
22420
22421```typescript
22422import {uniqWith} from 'rambda'
22423
22424describe('R.uniqWith', () => {
22425 it('happy', () => {
22426 const input = [
22427 {
22428 id: 0,
22429 title: 'foo',
22430 },
22431 {
22432 id: 1,
22433 title: 'bar',
22434 },
22435 {
22436 id: 2,
22437 title: 'baz',
22438 },
22439 {
22440 id: 3,
22441 title: 'foo',
22442 },
22443 {
22444 id: 4,
22445 title: 'bar',
22446 },
22447 ]
22448
22449 const fn = (x: any, y: any) => x.title === y.title
22450
22451 const result = uniqWith(fn, input)
22452 result // $ExpectType { id: number; title: string; }[]
22453 })
22454})
22455```
22456
22457</details>
22458
22459[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#uniqWith)
22460
22461### unless
22462
22463```typescript
22464
22465unless<T, U>(predicate: (x: T) => boolean, whenFalseFn: (x: T) => U, obj: T): U
22466```
22467
22468The method returns function that will be called with argument `input`.
22469
22470If `predicate(input)` returns `false`, then the end result will be the outcome of `whenFalse(input)`.
22471
22472In the other case, the final output will be the `input` itself.
22473
22474```javascript
22475const fn = R.unless(
22476 x => x > 2,
22477 x => x + 10
22478)
22479
22480const result = [
22481 fn(1),
22482 fn(5)
22483]
22484// => [11, 5]
22485```
22486
22487<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20fn%20%3D%20R.unless(%0A%20%20x%20%3D%3E%20x%20%3E%202%2C%0A%20%20x%20%3D%3E%20x%20%2B%2010%0A)%0A%0Aconst%20result%20%3D%20%5B%0A%20%20fn(1)%2C%0A%20%20fn(5)%0A%5D%0A%2F%2F%20%3D%3E%20%5B11%2C%205%5D">Try this <strong>R.unless</strong> example in Rambda REPL</a>
22488
22489<details>
22490
22491<summary>All Typescript definitions</summary>
22492
22493```typescript
22494unless<T, U>(predicate: (x: T) => boolean, whenFalseFn: (x: T) => U, obj: T): U;
22495unless<T, U>(predicate: (x: T) => boolean, whenFalseFn: (x: T) => U): (obj: T) => U;
22496```
22497
22498</details>
22499
22500<details>
22501
22502<summary><strong>R.unless</strong> source</summary>
22503
22504```javascript
22505export function unless(predicate, whenFalse){
22506 if (arguments.length === 1){
22507 return _whenFalse => unless(predicate, _whenFalse)
22508 }
22509
22510 return input => {
22511 if (predicate(input)) return input
22512
22513 return whenFalse(input)
22514 }
22515}
22516```
22517
22518</details>
22519
22520<details>
22521
22522<summary><strong>Tests</strong></summary>
22523
22524```javascript
22525import { inc } from './inc'
22526import { isNil } from './isNil'
22527import { unless } from './unless'
22528
22529const safeInc = unless(isNil, inc)
22530
22531test('happy', () => {
22532 expect(safeInc(null)).toBeNull()
22533 expect(safeInc(1)).toBe(2)
22534})
22535
22536test('curried', () => {
22537 const safeIncCurried = unless(isNil)(inc)
22538 expect(safeIncCurried(null)).toBeNull()
22539 expect(safeIncCurried(1)).toBe(2)
22540})
22541```
22542
22543</details>
22544
22545<details>
22546
22547<summary><strong>Typescript</strong> test</summary>
22548
22549```typescript
22550import {unless, isNil, inc} from 'rambda'
22551
22552describe('R.unless', () => {
22553 it('happy', () => {
22554 const safeInc = unless<any, number>(isNil, inc)
22555 const result = [safeInc(null), safeInc(1)]
22556 result[0] // $ExpectType number
22557 result[1] // $ExpectType number
22558 })
22559
22560 it('it needs explicitly declared types', () => {
22561 const safeInc = unless(x => x > 5, inc)
22562 const result = safeInc(1)
22563 result // $ExpectType number
22564 })
22565})
22566```
22567
22568</details>
22569
22570*4 failed Ramda.unless specs*
22571
22572> :boom: Reason for the failure: Rambda library doesn't have `R.of`
22573
22574[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#unless)
22575
22576### update
22577
22578```typescript
22579
22580update<T>(index: number, newValue: T, list: readonly T[]): T[]
22581```
22582
22583It returns a copy of `list` with updated element at `index` with `newValue`.
22584
22585```javascript
22586const index = 2
22587const newValue = 88
22588const list = [1, 2, 3, 4, 5]
22589
22590const result = R.update(index, newValue, list)
22591// => [1, 2, 88, 4, 5]
22592```
22593
22594<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20index%20%3D%202%0Aconst%20newValue%20%3D%2088%0Aconst%20list%20%3D%20%5B1%2C%202%2C%203%2C%204%2C%205%5D%0A%0Aconst%20result%20%3D%20R.update(index%2C%20newValue%2C%20list)%0A%2F%2F%20%3D%3E%20%5B1%2C%202%2C%2088%2C%204%2C%205%5D">Try this <strong>R.update</strong> example in Rambda REPL</a>
22595
22596<details>
22597
22598<summary>All Typescript definitions</summary>
22599
22600```typescript
22601update<T>(index: number, newValue: T, list: readonly T[]): T[];
22602update<T>(index: number, newValue: T): (list: readonly T[]) => T[];
22603```
22604
22605</details>
22606
22607<details>
22608
22609<summary><strong>R.update</strong> source</summary>
22610
22611```javascript
22612import { curry } from './curry'
22613
22614function updateFn(
22615 index, newValue, list
22616){
22617 const arrClone = list.slice()
22618
22619 return arrClone.fill(
22620 newValue, index, index + 1
22621 )
22622}
22623
22624export const update = curry(updateFn)
22625```
22626
22627</details>
22628
22629<details>
22630
22631<summary><strong>Tests</strong></summary>
22632
22633```javascript
22634import { update } from './update'
22635
22636const list = [ 1, 2, 3 ]
22637
22638test('happy', () => {
22639 const newValue = 8
22640 const index = 1
22641 const result = update(
22642 index, newValue, list
22643 )
22644 const curriedResult = update(index, newValue)(list)
22645 const tripleCurriedResult = update(index)(newValue)(list)
22646
22647 const expected = [ 1, 8, 3 ]
22648 expect(result).toEqual(expected)
22649 expect(curriedResult).toEqual(expected)
22650 expect(tripleCurriedResult).toEqual(expected)
22651})
22652
22653test('list has no such index', () => {
22654 const newValue = 8
22655 const index = 10
22656 const result = update(
22657 index, newValue, list
22658 )
22659
22660 expect(result).toEqual(list)
22661})
22662```
22663
22664</details>
22665
22666<details>
22667
22668<summary><strong>Typescript</strong> test</summary>
22669
22670```typescript
22671import {update} from 'rambda'
22672
22673describe('R.update', () => {
22674 it('happy', () => {
22675 const result = update(1, 0, [1, 2, 3])
22676 result // $ExpectType number[]
22677 })
22678})
22679```
22680
22681</details>
22682
22683<details>
22684
22685<summary>1 failed <italic>Ramda.update</italic> specs
22686
22687> :boom: Reason for the failure: Ramda method accepts an array-like object
22688</summary>
22689
22690```javascript
22691var R = require('../../../../dist/rambda.js');
22692var eq = require('./shared/eq');
22693
22694describe('update', function() {
22695 it('accepts an array-like object', function() {
22696 function args() {
22697 return arguments;
22698 }
22699 eq(R.update(2, 4, args(0, 1, 2, 3)), [0, 1, 4, 3]);
22700 });
22701});
22702```
22703
22704</details>
22705
22706[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#update)
22707
22708### values
22709
22710```typescript
22711
22712values<T extends object, K extends keyof T>(obj: T): T[K][]
22713```
22714
22715With correct input, this is nothing more than `Object.values(obj)`. If `obj` is not an object, then it returns an empty array.
22716
22717```javascript
22718const obj = {a:1, b:2}
22719
22720R.values(obj)
22721// => [1, 2]
22722```
22723
22724<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20obj%20%3D%20%7Ba%3A1%2C%20b%3A2%7D%0A%0AR.values(obj)%0A%2F%2F%20%3D%3E%20%5B1%2C%202%5D">Try this <strong>R.values</strong> example in Rambda REPL</a>
22725
22726<details>
22727
22728<summary>All Typescript definitions</summary>
22729
22730```typescript
22731values<T extends object, K extends keyof T>(obj: T): T[K][];
22732```
22733
22734</details>
22735
22736<details>
22737
22738<summary><strong>R.values</strong> source</summary>
22739
22740```javascript
22741import { type } from './type'
22742
22743export function values(obj){
22744 if (type(obj) !== 'Object') return []
22745
22746 return Object.values(obj)
22747}
22748```
22749
22750</details>
22751
22752<details>
22753
22754<summary><strong>Tests</strong></summary>
22755
22756```javascript
22757import { values } from './values'
22758
22759test('happy', () => {
22760 expect(values({
22761 a : 1,
22762 b : 2,
22763 c : 3,
22764 })).toEqual([ 1, 2, 3 ])
22765})
22766
22767test('with bad input', () => {
22768 expect(values(null)).toEqual([])
22769 expect(values(undefined)).toEqual([])
22770 expect(values(55)).toEqual([])
22771 expect(values('foo')).toEqual([])
22772 expect(values(true)).toEqual([])
22773 expect(values(false)).toEqual([])
22774 expect(values(NaN)).toEqual([])
22775 expect(values(Infinity)).toEqual([])
22776 expect(values([])).toEqual([])
22777})
22778```
22779
22780</details>
22781
22782<details>
22783
22784<summary><strong>Typescript</strong> test</summary>
22785
22786```typescript
22787import {values} from 'rambda'
22788
22789describe('R.values', () => {
22790 it('happy', () => {
22791 const result = values({
22792 a: 1,
22793 b: 2,
22794 c: 3,
22795 })
22796 result // $ExpectType number[]
22797 })
22798})
22799```
22800
22801</details>
22802
22803[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#values)
22804
22805### view
22806
22807```typescript
22808
22809view<T, U>(lens: Lens): (target: T) => U
22810```
22811
22812It returns the value of `lens` focus over `target` object.
22813
22814```javascript
22815const lens = R.lensProp('x')
22816
22817R.view(lens, {x: 1, y: 2}) //=> 1
22818R.view(lens, {x: 4, y: 2}) //=> 4
22819```
22820
22821<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20lens%20%3D%20R.lensProp('x')%0A%0AR.view(lens%2C%20%7Bx%3A%201%2C%20y%3A%202%7D)%20%2F%2F%3D%3E%201%0AR.view(lens%2C%20%7Bx%3A%204%2C%20y%3A%202%7D)%20%2F%2F%3D%3E%204">Try this <strong>R.view</strong> example in Rambda REPL</a>
22822
22823<details>
22824
22825<summary>All Typescript definitions</summary>
22826
22827```typescript
22828view<T, U>(lens: Lens): (target: T) => U;
22829view<T, U>(lens: Lens, target: T): U;
22830```
22831
22832</details>
22833
22834<details>
22835
22836<summary><strong>R.view</strong> source</summary>
22837
22838```javascript
22839const Const = x => ({
22840 x,
22841 map : fn => Const(x),
22842})
22843
22844export function view(lens, target){
22845 if (arguments.length === 1) return _target => view(lens, _target)
22846
22847 return lens(Const)(target).x
22848}
22849```
22850
22851</details>
22852
22853<details>
22854
22855<summary><strong>Tests</strong></summary>
22856
22857```javascript
22858import { assoc } from './assoc'
22859import { lens } from './lens'
22860import { prop } from './prop'
22861import { view } from './view'
22862
22863const testObject = { foo : 'Led Zeppelin' }
22864const assocLens = lens(prop('foo'), assoc('foo'))
22865
22866test('happy', () => {
22867 expect(view(assocLens, testObject)).toEqual('Led Zeppelin')
22868})
22869```
22870
22871</details>
22872
22873<details>
22874
22875<summary><strong>Typescript</strong> test</summary>
22876
22877```typescript
22878import {lens, view, assoc} from 'rambda'
22879
22880interface Input {
22881 foo: string,
22882}
22883
22884const testObject: Input = {
22885 foo: 'Led Zeppelin',
22886}
22887
22888const fooLens = lens<Input, string, string>((x: Input) => {
22889 return x.foo
22890}, assoc('foo'))
22891
22892describe('R.view', () => {
22893 it('happt', () => {
22894 const result = view<Input, string>(fooLens, testObject)
22895 result // $ExpectType string
22896 })
22897})
22898```
22899
22900</details>
22901
22902[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#view)
22903
22904### when
22905
22906```typescript
22907
22908when<T, U>(predicate: (x: T) => boolean, whenTrueFn: (a: T) => U, input: T): U
22909```
22910
22911<details>
22912
22913<summary>All Typescript definitions</summary>
22914
22915```typescript
22916when<T, U>(predicate: (x: T) => boolean, whenTrueFn: (a: T) => U, input: T): U;
22917when<T, U>(predicate: (x: T) => boolean, whenTrueFn: (a: T) => U): (input: T) => U;
22918when<T, U>(predicate: (x: T) => boolean): FunctionToolbelt.Curry<(whenTrueFn: (a: T) => U, input: T) => U>;
22919```
22920
22921</details>
22922
22923<details>
22924
22925<summary><strong>R.when</strong> source</summary>
22926
22927```javascript
22928import { curry } from './curry'
22929
22930function whenFn(
22931 predicate, whenTrueFn, input
22932){
22933 if (!predicate(input)) return input
22934
22935 return whenTrueFn(input)
22936}
22937
22938export const when = curry(whenFn)
22939```
22940
22941</details>
22942
22943<details>
22944
22945<summary><strong>Tests</strong></summary>
22946
22947```javascript
22948import { add } from './add'
22949import { when } from './when'
22950
22951const predicate = x => typeof x === 'number'
22952
22953test('happy', () => {
22954 const fn = when(predicate, add(11))
22955 expect(fn(11)).toBe(22)
22956 expect(fn('foo')).toBe('foo')
22957})
22958```
22959
22960</details>
22961
22962<details>
22963
22964<summary><strong>Typescript</strong> test</summary>
22965
22966```typescript
22967import {when} from 'rambda'
22968
22969const predicate = (x: number) => x > 2
22970const whenTrueFn = (x: number) => x + 2
22971
22972describe('R.when', () => {
22973 it('happy', () => {
22974 const result = when(predicate, whenTrueFn, 1)
22975 result // $ExpectType number
22976 })
22977
22978 it('curry 1', () => {
22979 const fn = when(predicate, whenTrueFn)
22980 const result = fn(1)
22981 result // $ExpectType number
22982 })
22983
22984 it('curry 2 require explicit types', () => {
22985 const fn = when<number, number>(predicate)(whenTrueFn)
22986 const result = fn(1)
22987 result // $ExpectType number
22988 })
22989
22990 it('curry 3 require explicit types', () => {
22991 const result = when<number, number>(predicate)(whenTrueFn, 1)
22992 result // $ExpectType number
22993 })
22994})
22995```
22996
22997</details>
22998
22999[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#when)
23000
23001### where
23002
23003```typescript
23004
23005where<T, U>(conditions: T, input: U): boolean
23006```
23007
23008It returns `true` if all each property in `conditions` returns `true` when applied to corresponding property in `input` object.
23009
23010```javascript
23011const condition = R.where({
23012 a : x => typeof x === "string",
23013 b : x => x === 4
23014})
23015const input = {
23016 a : "foo",
23017 b : 4,
23018 c : 11,
23019}
23020
23021const result = condition(input)
23022// => true
23023```
23024
23025<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20condition%20%3D%20R.where(%7B%0A%20%20a%20%3A%20x%20%3D%3E%20typeof%20x%20%3D%3D%3D%20%22string%22%2C%0A%20%20b%20%3A%20x%20%3D%3E%20x%20%3D%3D%3D%204%0A%7D)%0Aconst%20input%20%3D%20%7B%0A%20%20a%20%3A%20%22foo%22%2C%0A%20%20b%20%3A%204%2C%0A%20%20c%20%3A%2011%2C%0A%7D%0A%0Aconst%20result%20%3D%20condition(input)%20%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.where</strong> example in Rambda REPL</a>
23026
23027<details>
23028
23029<summary>All Typescript definitions</summary>
23030
23031```typescript
23032where<T, U>(conditions: T, input: U): boolean;
23033where<T>(conditions: T): <U>(input: U) => boolean;
23034where<ObjFunc2, U>(conditions: ObjFunc2, input: U): boolean;
23035where<ObjFunc2>(conditions: ObjFunc2): <U>(input: U) => boolean;
23036```
23037
23038</details>
23039
23040<details>
23041
23042<summary><strong>R.where</strong> source</summary>
23043
23044```javascript
23045export function where(conditions, input){
23046 if (input === undefined){
23047 return _input => where(conditions, _input)
23048 }
23049 let flag = true
23050 for (const prop in conditions){
23051 const result = conditions[ prop ](input[ prop ])
23052 if (flag && result === false){
23053 flag = false
23054 }
23055 }
23056
23057 return flag
23058}
23059```
23060
23061</details>
23062
23063<details>
23064
23065<summary><strong>Tests</strong></summary>
23066
23067```javascript
23068import { equals } from './equals'
23069import { where } from './where'
23070
23071test('when true', () => {
23072 const predicate = where({
23073 a : equals('foo'),
23074 b : equals('bar'),
23075 })
23076 expect(predicate({
23077 a : 'foo',
23078 b : 'bar',
23079 x : 11,
23080 y : 19,
23081 })).toEqual(true)
23082})
23083
23084test('when false', () => {
23085 const predicate = where({
23086 a : equals('foo'),
23087 b : equals('baz'),
23088 })
23089 expect(predicate({
23090 a : 'foo',
23091 b : 'bar',
23092 x : 11,
23093 y : 19,
23094 })).toEqual(false)
23095})
23096```
23097
23098</details>
23099
23100<details>
23101
23102<summary><strong>Typescript</strong> test</summary>
23103
23104```typescript
23105import {where, equals} from 'rambda'
23106
23107describe('R.where', () => {
23108 it('happy', () => {
23109 const input = {
23110 a: 'foo',
23111 b: 'bar',
23112 x: 11,
23113 y: 19,
23114 }
23115 const conditions = {
23116 a: equals('foo'),
23117 b: equals('bar'),
23118 }
23119 const result = where(conditions, input)
23120 const curriedResult = where(conditions)(input)
23121 result // $ExpectType boolean
23122 curriedResult // $ExpectType boolean
23123 })
23124})
23125```
23126
23127</details>
23128
23129*2 failed Ramda.where specs*
23130
23131> :boom: Reason for the failure: Ramba method looks inside `prototype` property
23132
23133[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#where)
23134
23135### whereEq
23136
23137```typescript
23138
23139whereEq<T, U>(condition: T, input: U): boolean
23140```
23141
23142It will return `true` if all of `input` object fully or partially include `rule` object.
23143
23144```javascript
23145const condition = { a : { b : 1 } }
23146const input = {
23147 a : { b : 1 },
23148 c : 2
23149}
23150
23151const result = whereEq(condition, input)
23152//=> true
23153```
23154
23155<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20condition%20%3D%20%7B%20a%20%3A%20%7B%20b%20%3A%201%20%7D%20%7D%0Aconst%20input%20%3D%20%7B%0A%20%20a%20%3A%20%7B%20b%20%3A%201%20%7D%2C%0A%20%20c%20%3A%202%0A%7D%0A%0Aconst%20result%20%3D%20whereEq(condition%2C%20input)%0A%2F%2F%3D%3E%20true">Try this <strong>R.whereEq</strong> example in Rambda REPL</a>
23156
23157<details>
23158
23159<summary>All Typescript definitions</summary>
23160
23161```typescript
23162whereEq<T, U>(condition: T, input: U): boolean;
23163whereEq<T>(condition: T): <U>(input: U) => boolean;
23164```
23165
23166</details>
23167
23168<details>
23169
23170<summary><strong>R.whereEq</strong> source</summary>
23171
23172```javascript
23173import { equals } from './equals'
23174import { filter } from './filter'
23175
23176export function whereEq(condition, input){
23177 if (arguments.length === 1){
23178 return _input => whereEq(condition, _input)
23179 }
23180
23181 const result = filter((conditionValue, conditionProp) =>
23182 equals(conditionValue, input[ conditionProp ]),
23183 condition)
23184
23185 return Object.keys(result).length === Object.keys(condition).length
23186}
23187```
23188
23189</details>
23190
23191<details>
23192
23193<summary><strong>Tests</strong></summary>
23194
23195```javascript
23196import { whereEq } from './whereEq'
23197
23198test('when true', () => {
23199 const condition = { a : 1 }
23200 const input = {
23201 a : 1,
23202 b : 2,
23203 }
23204
23205 const result = whereEq(condition, input)
23206 const expectedResult = true
23207
23208 expect(result).toEqual(expectedResult)
23209})
23210
23211test('when false', () => {
23212 const condition = { a : 1 }
23213 const input = { b : 2 }
23214
23215 const result = whereEq(condition, input)
23216 const expectedResult = false
23217
23218 expect(result).toEqual(expectedResult)
23219})
23220
23221test('with nested object', () => {
23222 const condition = { a : { b : 1 } }
23223 const input = {
23224 a : { b : 1 },
23225 c : 2,
23226 }
23227
23228 const result = whereEq(condition)(input)
23229 const expectedResult = true
23230
23231 expect(result).toEqual(expectedResult)
23232})
23233
23234test('with wrong input', () => {
23235 const condition = { a : { b : 1 } }
23236
23237 expect(() => whereEq(condition, null)).toThrowWithMessage(TypeError,
23238 'Cannot read property \'a\' of null')
23239})
23240```
23241
23242</details>
23243
23244<details>
23245
23246<summary><strong>Typescript</strong> test</summary>
23247
23248```typescript
23249import {whereEq} from 'rambda'
23250
23251describe('R.whereEq', () => {
23252 it('happy', () => {
23253 const result = whereEq({a: {b: 2}}, {b: 2})
23254 const curriedResult = whereEq({a: {b: 2}})({b: 2})
23255 result // $ExpectType boolean
23256 curriedResult // $ExpectType boolean
23257 })
23258})
23259```
23260
23261</details>
23262
23263*2 failed Ramda.whereEq specs*
23264
23265> :boom: Reason for the failure: Ramba method looks inside `prototype` property | Rambda.equals doesn't support equality of functions
23266
23267[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#whereEq)
23268
23269### without
23270
23271```typescript
23272
23273without<T>(matchAgainst: readonly T[], source: readonly T[]): T[]
23274```
23275
23276It will return a new array, based on all members of `source` list that are not part of `matchAgainst` list.
23277
23278> :boom: `R.equals` is used to determine equality
23279
23280```javascript
23281const source = [1, 2, 3, 4]
23282const matchAgainst = [2, 3]
23283
23284const result = R.without(matchAgainst, source)
23285// => [1, 4]
23286```
23287
23288<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20source%20%3D%20%5B1%2C%202%2C%203%2C%204%5D%0Aconst%20matchAgainst%20%3D%20%5B2%2C%203%5D%0A%0Aconst%20result%20%3D%20R.without(matchAgainst%2C%20source)%0A%2F%2F%20%3D%3E%20%5B1%2C%204%5D">Try this <strong>R.without</strong> example in Rambda REPL</a>
23289
23290<details>
23291
23292<summary>All Typescript definitions</summary>
23293
23294```typescript
23295without<T>(matchAgainst: readonly T[], source: readonly T[]): T[];
23296without<T>(matchAgainst: readonly T[]): (source: readonly T[]) => T[];
23297```
23298
23299</details>
23300
23301<details>
23302
23303<summary><strong>R.without</strong> source</summary>
23304
23305```javascript
23306import { includes } from './includes'
23307import { reduce } from './reduce'
23308
23309export function without(matchAgainst, source){
23310 if (source === undefined){
23311 return _source => without(matchAgainst, _source)
23312 }
23313
23314 return reduce(
23315 (prev, current) =>
23316 includes(current, matchAgainst) ? prev : prev.concat(current),
23317 [],
23318 source
23319 )
23320}
23321```
23322
23323</details>
23324
23325<details>
23326
23327<summary><strong>Tests</strong></summary>
23328
23329```javascript
23330import { without } from './without'
23331
23332test('should return a new list without values in the first argument ', () => {
23333 const itemsToOmit = [ 'A', 'B', 'C' ]
23334 const collection = [ 'A', 'B', 'C', 'D', 'E', 'F' ]
23335
23336 expect(without(itemsToOmit, collection)).toEqual([ 'D', 'E', 'F' ])
23337 expect(without(itemsToOmit)(collection)).toEqual([ 'D', 'E', 'F' ])
23338})
23339
23340test('ramda test', () => {
23341 expect(without([ 1, 2 ])([ 1, 2, 1, 3, 4 ])).toEqual([ 3, 4 ])
23342})
23343```
23344
23345</details>
23346
23347<details>
23348
23349<summary><strong>Typescript</strong> test</summary>
23350
23351```typescript
23352import {without} from 'rambda'
23353
23354const itemsToOmit = ['A', 'B', 'C']
23355const collection = ['A', 'B', 'C', 'D', 'E', 'F']
23356
23357describe('R.without', () => {
23358 it('happy', () => {
23359 const result = without(itemsToOmit, collection)
23360
23361 result // $ExpectType string[]
23362 })
23363 it('curried', () => {
23364 const result = without(itemsToOmit)(collection)
23365
23366 result // $ExpectType string[]
23367 })
23368})
23369```
23370
23371</details>
23372
23373<details>
23374
23375<summary>2 failed <italic>Ramda.without</italic> specs
23376
23377> :boom: Reason for the failure: Ramda method act as a transducer | Ramda method pass to `equals` method
23378</summary>
23379
23380```javascript
23381var R = require('../../../../dist/rambda.js');
23382var eq = require('./shared/eq');
23383
23384describe('without', function() {
23385 it('can act as a transducer', function() {
23386 eq(R.into([], R.without([1]), [1]), []);
23387 });
23388 it('has R.equals semantics', function() {
23389 function Just(x) { this.value = x; }
23390 Just.prototype.equals = function(x) {
23391 return x instanceof Just && R.equals(x.value, this.value);
23392 };
23393 eq(R.without([0], [-0]).length, 1);
23394 eq(R.without([-0], [0]).length, 1);
23395 eq(R.without([NaN], [NaN]).length, 0);
23396 eq(R.without([[1]], [[1]]).length, 0);
23397 eq(R.without([new Just([42])], [new Just([42])]).length, 0);
23398 });
23399});
23400```
23401
23402</details>
23403
23404[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#without)
23405
23406### xor
23407
23408```typescript
23409
23410xor(x: boolean, y: boolean): boolean
23411```
23412
23413```javascript
23414const result = [
23415 xor(true, true),
23416 xor(false, false),
23417 xor(false, true),
23418]
23419// => [false, false, true]
23420```
23421
23422<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20%5B%0A%20%20xor(true%2C%20true)%2C%0A%20%20xor(false%2C%20false)%2C%0A%20%20xor(false%2C%20true)%2C%0A%5D%0A%2F%2F%20%3D%3E%20%5Bfalse%2C%20false%2C%20true%5D">Try this <strong>R.xor</strong> example in Rambda REPL</a>
23423
23424<details>
23425
23426<summary>All Typescript definitions</summary>
23427
23428```typescript
23429xor(x: boolean, y: boolean): boolean;
23430xor(y: boolean): (y: boolean) => boolean;
23431```
23432
23433</details>
23434
23435<details>
23436
23437<summary><strong>R.xor</strong> source</summary>
23438
23439```javascript
23440export function xor(a, b){
23441 if (arguments.length === 1) return _b => xor(a, _b)
23442
23443 return Boolean(a) && !b || Boolean(b) && !a
23444}
23445```
23446
23447</details>
23448
23449<details>
23450
23451<summary><strong>Tests</strong></summary>
23452
23453```javascript
23454import { xor } from './xor'
23455
23456test('compares two values with exclusive or', () => {
23457 expect(xor(true, true)).toEqual(false)
23458 expect(xor(true, false)).toEqual(true)
23459 expect(xor(false, true)).toEqual(true)
23460 expect(xor(false, false)).toEqual(false)
23461})
23462
23463test('when both values are truthy, it should return false', () => {
23464 expect(xor(true, 'foo')).toEqual(false)
23465 expect(xor(42, true)).toEqual(false)
23466 expect(xor('foo', 42)).toEqual(false)
23467 expect(xor({}, true)).toEqual(false)
23468 expect(xor(true, [])).toEqual(false)
23469 expect(xor([], {})).toEqual(false)
23470 expect(xor(new Date(), true)).toEqual(false)
23471 expect(xor(true, Infinity)).toEqual(false)
23472 expect(xor(Infinity, new Date())).toEqual(false)
23473})
23474
23475test('when both values are falsy, it should return false', () => {
23476 expect(xor(null, false)).toEqual(false)
23477 expect(xor(false, undefined)).toEqual(false)
23478 expect(xor(undefined, null)).toEqual(false)
23479 expect(xor(0, false)).toEqual(false)
23480 expect(xor(false, NaN)).toEqual(false)
23481 expect(xor(NaN, 0)).toEqual(false)
23482 expect(xor('', false)).toEqual(false)
23483})
23484
23485test('when one argument is truthy and the other is falsy, it should return true', () => {
23486 expect(xor('foo', null)).toEqual(true)
23487 expect(xor(null, 'foo')).toEqual(true)
23488 expect(xor(undefined, 42)).toEqual(true)
23489 expect(xor(42, undefined)).toEqual(true)
23490 expect(xor(Infinity, NaN)).toEqual(true)
23491 expect(xor(NaN, Infinity)).toEqual(true)
23492 expect(xor({}, '')).toEqual(true)
23493 expect(xor('', {})).toEqual(true)
23494 expect(xor(new Date(), 0)).toEqual(true)
23495 expect(xor(0, new Date())).toEqual(true)
23496 expect(xor([], null)).toEqual(true)
23497 expect(xor(undefined, [])).toEqual(true)
23498})
23499```
23500
23501</details>
23502
23503<details>
23504
23505<summary><strong>Typescript</strong> test</summary>
23506
23507```typescript
23508import {xor} from 'rambda'
23509
23510describe('R.xor', () => {
23511 it('happy', () => {
23512 xor(true, false) // $ExpectType boolean
23513 })
23514 it('curry', () => {
23515 xor(true)(false) // $ExpectType boolean
23516 })
23517})
23518```
23519
23520</details>
23521
23522<details>
23523
23524<summary>1 failed <italic>Ramda.xor</italic> specs
23525
23526> :boom: Reason for the failure: Ramda method support empty call of method
23527</summary>
23528
23529```javascript
23530var R = require('../../../../dist/rambda.js');
23531var eq = require('./shared/eq');
23532
23533describe('xor', function() {
23534 it('returns a curried function', function() {
23535 eq(R.xor()(true)(true), false);
23536 eq(R.xor()(true)(false), true);
23537 eq(R.xor()(false)(true), true);
23538 eq(R.xor()(false)(false), false);
23539 });
23540});
23541```
23542
23543</details>
23544
23545[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#xor)
23546
23547### zip
23548
23549```typescript
23550
23551zip<K, V>(x: readonly K[], y: readonly V[]): KeyValuePair<K, V>[]
23552```
23553
23554It will return a new array containing tuples of equally positions items from both `x` and `y` lists.
23555
23556The returned list will be truncated to match the length of the shortest supplied list.
23557
23558```javascript
23559const x = [1, 2]
23560const y = ['A', 'B']
23561R.zip(x, y)
23562// => [[1, 'A'], [2, 'B']]
23563
23564// truncates to shortest list
23565R.zip([...x, 3], ['A', 'B'])
23566// => [[1, 'A'], [2, 'B']]
23567```
23568
23569<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20x%20%3D%20%5B1%2C%202%5D%0Aconst%20y%20%3D%20%5B'A'%2C%20'B'%5D%0AR.zip(x%2C%20y)%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%20'A'%5D%2C%20%5B2%2C%20'B'%5D%5D%0A%0A%2F%2F%20truncates%20to%20shortest%20list%0AR.zip(%5B...x%2C%203%5D%2C%20%5B'A'%2C%20'B'%5D)%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%20'A'%5D%2C%20%5B2%2C%20'B'%5D%5D">Try this <strong>R.zip</strong> example in Rambda REPL</a>
23570
23571<details>
23572
23573<summary>All Typescript definitions</summary>
23574
23575```typescript
23576zip<K, V>(x: readonly K[], y: readonly V[]): KeyValuePair<K, V>[];
23577zip<K>(x: readonly K[]): <V>(y: readonly V[]) => KeyValuePair<K, V>[];
23578```
23579
23580</details>
23581
23582<details>
23583
23584<summary><strong>R.zip</strong> source</summary>
23585
23586```javascript
23587export function zip(left, right){
23588 if (arguments.length === 1) return _right => zip(left, _right)
23589
23590 const result = []
23591 const length = Math.min(left.length, right.length)
23592
23593 for (let i = 0; i < length; i++){
23594 result[ i ] = [ left[ i ], right[ i ] ]
23595 }
23596
23597 return result
23598}
23599```
23600
23601</details>
23602
23603<details>
23604
23605<summary><strong>Tests</strong></summary>
23606
23607```javascript
23608import { zip } from './zip'
23609
23610const array1 = [ 1, 2, 3 ]
23611const array2 = [ 'A', 'B', 'C' ]
23612
23613test('should return an array', () => {
23614 const actual = zip(array1)(array2)
23615 expect(actual).toBeInstanceOf(Array)
23616})
23617
23618test('should return and array or tuples', () => {
23619 const expected = [
23620 [ 1, 'A' ],
23621 [ 2, 'B' ],
23622 [ 3, 'C' ],
23623 ]
23624 const actual = zip(array1, array2)
23625 expect(actual).toEqual(expected)
23626})
23627
23628test('should truncate result to length of shorted input list', () => {
23629 const expectedA = [
23630 [ 1, 'A' ],
23631 [ 2, 'B' ],
23632 ]
23633 const actualA = zip([ 1, 2 ], array2)
23634 expect(actualA).toEqual(expectedA)
23635
23636 const expectedB = [
23637 [ 1, 'A' ],
23638 [ 2, 'B' ],
23639 ]
23640 const actualB = zip(array1, [ 'A', 'B' ])
23641 expect(actualB).toEqual(expectedB)
23642})
23643```
23644
23645</details>
23646
23647<details>
23648
23649<summary><strong>Typescript</strong> test</summary>
23650
23651```typescript
23652import {zip} from 'rambda'
23653
23654describe('R.zip', () => {
23655 it('happy', () => {
23656 const array1 = [1, 2, 3]
23657 const array2 = ['A', 'B', 'C']
23658
23659 const result = zip(array1)(array2)
23660 result // $ExpectType KeyValuePair<number, string>[]
23661 })
23662})
23663```
23664
23665</details>
23666
23667[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#zip)
23668
23669### zipObj
23670
23671```typescript
23672
23673zipObj<T>(keys: string[], values: T[]): { [index: string]: T }
23674```
23675
23676It will return a new object with keys of `keys` array and values of `values` array.
23677
23678```javascript
23679const keys = ['a', 'b', 'c']
23680
23681R.zipObj(keys, [1, 2, 3])
23682//=> {a: 1, b: 2, c: 3}
23683
23684// truncates to shortest list
23685R.zipObj(keys, [1, 2])
23686//=> {a: 1, b: 2}
23687```
23688
23689<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20result%20%3D%20const%20keys%20%3D%20%5B'a'%2C%20'b'%2C%20'c'%5D%0A%0AR.zipObj(keys%2C%20%5B1%2C%202%2C%203%5D)%0A%2F%2F%3D%3E%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D%0A%0A%2F%2F%20truncates%20to%20shortest%20list%0AR.zipObj(keys%2C%20%5B1%2C%202%5D)%0A%2F%2F%3D%3E%20%7Ba%3A%201%2C%20b%3A%202%7D">Try this <strong>R.zipObj</strong> example in Rambda REPL</a>
23690
23691<details>
23692
23693<summary>All Typescript definitions</summary>
23694
23695```typescript
23696zipObj<T>(keys: string[], values: T[]): { [index: string]: T };
23697zipObj(keys: string[]): <T>(values: T[]) => { [index: string]: T };
23698```
23699
23700</details>
23701
23702<details>
23703
23704<summary><strong>R.zipObj</strong> source</summary>
23705
23706```javascript
23707import { take } from './take'
23708
23709export function zipObj(keys, values){
23710 if (arguments.length === 1) return yHolder => zipObj(keys, yHolder)
23711
23712 return take(values.length, keys).reduce((
23713 prev, xInstance, i
23714 ) => {
23715 prev[ xInstance ] = values[ i ]
23716
23717 return prev
23718 }, {})
23719}
23720```
23721
23722</details>
23723
23724<details>
23725
23726<summary><strong>Tests</strong></summary>
23727
23728```javascript
23729import { equals } from './equals'
23730import { zipObj } from './zipObj'
23731
23732test('zipObj', () => {
23733 expect(zipObj([ 'a', 'b', 'c' ], [ 1, 2, 3 ])).toEqual({
23734 a : 1,
23735 b : 2,
23736 c : 3,
23737 })
23738})
23739
23740test('0', () => {
23741 expect(zipObj([ 'a', 'b' ])([ 1, 2, 3 ])).toEqual({
23742 a : 1,
23743 b : 2,
23744 })
23745})
23746
23747test('1', () => {
23748 expect(zipObj([ 'a', 'b', 'c' ])([ 1, 2 ])).toEqual({
23749 a : 1,
23750 b : 2,
23751 })
23752})
23753
23754test('ignore extra keys', () => {
23755 const result = zipObj([ 'a', 'b', 'c', 'd', 'e', 'f' ], [ 1, 2, 3 ])
23756 const expected = {
23757 a : 1,
23758 b : 2,
23759 c : 3,
23760 }
23761
23762 expect(equals(result, expected)).toBeTrue()
23763})
23764```
23765
23766</details>
23767
23768<details>
23769
23770<summary><strong>Typescript</strong> test</summary>
23771
23772```typescript
23773import {zipObj} from 'rambda'
23774
23775describe('R.zipObj', () => {
23776 it('happy', () => {
23777 const result = zipObj(['a', 'b', 'c', 'd', 'e', 'f'], [1, 2, 3])
23778 result // $ExpectType { [index: string]: number; }
23779 })
23780})
23781```
23782
23783</details>
23784
23785[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#zipObj)
23786
23787### zipWith
23788
23789```typescript
23790
23791zipWith<T, U, TResult>(fn: (x: T, y: U) => TResult, list1: readonly T[], list2: readonly U[]): TResult[]
23792```
23793
23794```javascript
23795const list1 = [ 10, 20, 30, 40 ]
23796const list2 = [ 100, 200 ]
23797
23798const result = R.zipWith(
23799 R.add, list1, list2
23800)
23801// => [110, 220]
23802```
23803
23804<a title="redirect to Rambda Repl site" href="https://rambda.now.sh?const%20list1%20%3D%20%5B%2010%2C%2020%2C%2030%2C%2040%20%5D%0Aconst%20list2%20%3D%20%5B%20100%2C%20200%20%5D%0A%0Aconst%20result%20%3D%20R.zipWith(%0A%20%20R.add%2C%20list1%2C%20list2%0A)%0A%2F%2F%20%3D%3E%20%5B110%2C%20220%5D">Try this <strong>R.zipWith</strong> example in Rambda REPL</a>
23805
23806<details>
23807
23808<summary>All Typescript definitions</summary>
23809
23810```typescript
23811zipWith<T, U, TResult>(fn: (x: T, y: U) => TResult, list1: readonly T[], list2: readonly U[]): TResult[];
23812zipWith<T, U, TResult>(fn: (x: T, y: U) => TResult, list1: readonly T[]): (list2: readonly U[]) => TResult[];
23813zipWith<T, U, TResult>(fn: (x: T, y: U) => TResult): (list1: readonly T[], list2: readonly U[]) => TResult[];
23814```
23815
23816</details>
23817
23818<details>
23819
23820<summary><strong>R.zipWith</strong> source</summary>
23821
23822```javascript
23823import { curry } from './curry'
23824import { take } from './take'
23825
23826function zipWithFn(
23827 fn, x, y
23828){
23829 return take(x.length > y.length ? y.length : x.length,
23830 x).map((xInstance, i) => fn(xInstance, y[ i ]))
23831}
23832
23833export const zipWith = curry(zipWithFn)
23834```
23835
23836</details>
23837
23838<details>
23839
23840<summary><strong>Tests</strong></summary>
23841
23842```javascript
23843import { add } from './add'
23844import { zipWith } from './zipWith'
23845
23846const list1 = [ 1, 2, 3 ]
23847const list2 = [ 10, 20, 30, 40 ]
23848const list3 = [ 100, 200 ]
23849
23850test('when second list is shorter', () => {
23851 const result = zipWith(
23852 add, list1, list3
23853 )
23854 expect(result).toEqual([ 101, 202 ])
23855})
23856
23857test('when second list is longer', () => {
23858 const result = zipWith(
23859 add, list1, list2
23860 )
23861 expect(result).toEqual([ 11, 22, 33 ])
23862})
23863```
23864
23865</details>
23866
23867<details>
23868
23869<summary><strong>Typescript</strong> test</summary>
23870
23871```typescript
23872import {zipWith} from 'rambda'
23873
23874const list1 = [1, 2]
23875const list2 = [10, 20, 30]
23876
23877describe('R.zipWith', () => {
23878 it('happy', () => {
23879 const result = zipWith(
23880 (x, y) => {
23881 x // $ExpectType number
23882 y // $ExpectType number
23883 return `${x}-${y}`
23884 },
23885 list1,
23886 list2
23887 )
23888
23889 result // $ExpectType string[]
23890 })
23891 it('curried', () => {
23892 const result = zipWith((x, y) => {
23893 x // $ExpectType unknown
23894 y // $ExpectType unknown
23895 return `${x}-${y}`
23896 })(list1, list2)
23897
23898 result // $ExpectType string[]
23899 })
23900})
23901```
23902
23903</details>
23904
23905[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#zipWith)
23906
23907## ➤ CHANGELOG
23908
239096.3.0
23910
23911- Add `R.takeLastWhile`
23912
23913- Add `R.dropWhile`
23914
23915- Add `R.eqProps`
23916
23917- Add `R.dropLastWhile`
23918
23919- Add `R.dropRepeats`
23920
23921- Add `R.dropRepeatsWith`
23922
23923- Add `R.evolve`
23924
23925- Add typings for `R.takeWhile` when iterable is a string
23926
239276.2.0
23928
23929- Add `R.props`
23930
23931- Add `R.zipWith`
23932
23933- Add `R.splitAt`
23934
23935- Add `R.splitWhen`
23936
23937- Close [Issue #547](https://github.com/selfrefactor/rambda/issues/547) - restore `readonly` declaration in Typescript definitions.
23938
23939- `R.append`/`R.prepend` now work only with arrays just like Ramda. Previous behaviour was for them to work with both arrays and strings.
23940
23941- Sync `R.pluck` typings with `@types/ramda` as there was a tiny difference.
23942
239436.1.0
23944
23945- Fix `R.and` wrong definition, because the function doesn't convert the result to boolean. This introduce another difference with `@types/ramda`.
23946
23947- Add `R.once`
23948
23949- Add `R.or`
23950
239516.0.1
23952
23953- Fix typing of `R.reject` as it wrongly declares that with object, it pass property to predicate.
23954
239556.0.0
23956
23957- Breaking change - `R.map`/`R.filter`/`R.reject`/`R.forEach`/`R.partition` doesn't pass index as second argument to the predicate, when looping over arrays. The old behaviour of *map*, *filter* and *forEach* can be found in Rambdax methods *R.mapIndexed*, *R.filterIndexed* and *R.forEachIndexed*.
23958
23959- Breaking change - `R.all`/`R.none`/`R.any`/`R.find`/`R.findLast`/`R.findIndex`/`R.findLastIndex` doesn't pass index as second argument to the predicate.
23960
23961- Change `R.assocPath` typings so the user can explicitly sets type of the new object
23962
23963- Typings of `R.assoc` match its `@types/ramda` counterpart.
23964
23965- Simplify `R.forEach` typings
23966
23967- Remove `ReadonlyArray<T>` pattern from Typescript definitions - not enough value for the noise it adds.
23968
239695.13.1
23970
23971- Fix wrong `R.takeWhile`
23972
239735.13.0
23974
23975- Add `R.takeWhile` method
23976
23977- Fix `R.lensPath` issue when using string as path input. The issue was introduced when fixing [Issue #524](https://github.com/selfrefactor/rambda/issues/524) in the previous release.
23978
239795.12.1
23980
23981- Close [Issue #524](https://github.com/selfrefactor/rambda/issues/524) -
23982 wrong `R.assocPath` when path includes numbers
23983
23984- `R.includes` throws on wrong input, i.e. `R.includes(1, null)`
23985
239865.12.0
23987
23988- Add `R.move` method
23989
23990- Add `R.union` method
23991
23992- Close [Issue #519](https://github.com/selfrefactor/rambda/issues/519) -
23993`ts-toolbelt` needs other type of export with `--isolatedModules` flag
23994
23995- Change `R.when` implementation and typings to match those of `Ramda`
23996
23997- `R.over` and `R.set` use `R.curry` instead of manual currying
23998
23999- `R.lensPath` typings support string as path, i.e. `'a.b'` instead of `['a', 'b']`
24000
24001- `R.equals` now supports negative zero just like `Ramda.equals`
24002
24003- `R.replace` uses `R.curry`
24004
240055.11.0
24006
24007Forgot to export `R.of` because of wrong marker in `files/index.d.ts`
24008
240095.10.0
24010
24011Close [Issue #514](https://github.com/selfrefactor/rambda/issues/514) -
24012wrong `R.length` with empty string
24013
24014Close [Issue #511](https://github.com/selfrefactor/rambda/issues/511) - error in `ts-toolbelt` library
24015
24016Close [Issue #510](https://github.com/selfrefactor/rambda/issues/510) - `R.clamp` should throw if min argument is greater than max argument
24017
24018- [PR #508](https://github.com/selfrefactor/rambda/pull/508) - add `R.of`
24019
24020- Definition of `R.curry` are not same as those of `@types/ramda`
24021
24022- Definitions of `R.either` is same as that of `R.both`
24023
24024- Definitions of `R.ifElse` no longer use `any` type
24025
24026- Definition of `R.flatten` requires passing type for the output
24027
24028- Fix definition of `R.propOr`, `R.dissoc`
24029
24030- Fix curried definitions of `R.take`, `R.takeLast`, `R.drop` and `R.dropLast`
24031
24032- 5.9.0
24033
24034- `R.pickAll` definition allows passing string as path to search.
24035
24036- `R.propEq` definition is now similar to that in `@types/ramda`.
24037
24038- `R.none` matches `R.all` implementation and pass index as second argument to predicate input.
24039
24040- `R.reduce` - drop support for object as iterable. Now it throws the same error as Ramda. Also instead of returning the initial value when iterable is `undefined`, now it throws.
24041
24042Add index as additional argument to the Typescript definitions of the following methods:
24043
24044- R.all
24045- R.find
24046- R.findLast
24047- R.findIndex
24048- R.findLastIndex
24049
24050- 5.8.0
24051
24052Add `R.mergeAll`
24053Add `R.mergeDeepRight`
24054Add `R.mergeLeft`
24055Add `R.partition`
24056Add `R.pathEq`
24057Add `R.tryCatch`
24058Add `R.unless`
24059Add `R.whereEq`
24060Add `R.where`
24061
24062- Add `R.last` typing for empty array
24063
24064- 5.7.0 Revert [PR #469](https://github.com/selfrefactor/rambda/pull/469) as `R.curry` was slow | Also now `R.flip` throws if arity is greater than or equal to 5
24065
24066- 5.6.3 Merge several PRs of [@farwayer](https://github.com/farwayer)
24067
24068- [PR #482](https://github.com/selfrefactor/rambda/pull/482) - improve `R.forEach` performance by not using `R.map`
24069
24070- [PR #485](https://github.com/selfrefactor/rambda/pull/485) - improve `R.map` performance
24071
24072- [PR #482](https://github.com/selfrefactor/rambda/pull/486) - improve `R.reduce` performance
24073
24074- Fix missing high arity typings for `R.compose/pipe`
24075
24076- `R.merge` definitions match those of `@types/ramda`
24077
24078- Remove `dist` folder from Rambda repo
24079
24080- 5.6.2
24081
24082Close [Issue #476](https://github.com/selfrefactor/rambda/issues/476) - typesafe `R.propEq` definitions
24083
24084Approve [PR #477](https://github.com/selfrefactor/rambda/pull/477) - fix `R.groupWith` when list length is 1
24085
24086- 5.6.1
24087
24088Update `ts-toolbelt` files as now there is update pipeline for it.
24089
24090Approve [PR #474](https://github.com/selfrefactor/rambda/pull/474) - intruduce internal `isArray` helper
24091
24092- 5.6.0
24093
24094Approve [PR #469](https://github.com/selfrefactor/rambda/pull/469) - R.flip supports any arity | implement `R.curry` with `R.curryN` add `R.applySpec`
24095
24096- 5.5.0
24097
24098Close [Issue #464](https://github.com/selfrefactor/rambda/issues/464) - `R.flip` should handle functions with arity above 2
24099
24100Close [Issue #468](https://github.com/selfrefactor/rambda/issues/468) - `fs-extra` should be dev dependency as it was wrongly added as production dependency in `5.2.0`
24101
24102`R.flip` typings now match `@types/ramda` typings
24103
24104Add `R.hasPath` method
24105
24106Add `R.mathMod` typings
24107
24108- 5.4.3
24109
24110Fix `R.omit` typings
24111
24112- 5.4.2
24113
24114Fix `R.pick` typings
24115
24116> Close [Issue #460](https://github.com/selfrefactor/rambda/issues/460) - `R.paths` should be curried
24117
24118- 5.4.1
24119
24120> Close [Issue #458](https://github.com/selfrefactor/rambda/issues/458) - wrong `R.propIs` typing
24121
24122- 5.4.0
24123
24124> Close [Issue #408](https://github.com/selfrefactor/rambda/issues/408) - add `R.chain`
24125
24126- 5.3.0
24127
24128> Close [Issue #430](https://github.com/selfrefactor/rambda/issues/430) - add `R.when`
24129
24130Also restore `R.converge`, `R.findLast`, `R.findLastIndex` and `R.curryN` as I have forgotten to export them when releasing `5.2.0`.
24131
24132- 5.2.1
24133
24134Fix Typescript comment for every method
24135
24136- 5.2.0
24137
24138Release new documentation site
24139
24140`Ramda` repo now holds all `Rambdax` methods and tests
24141
24142- 5.1.1
24143
24144Add `R.converge` and `R.curryN` from [PR #412](https://github.com/selfrefactor/rambda/pull/412)
24145
24146Close [Issue #410](https://github.com/selfrefactor/rambda/issues/410) - wrong implementation of `R.groupWith`
24147
24148Close [Issue #411](https://github.com/selfrefactor/rambda/issues/411) - change the order of declared `R.map` typings rules
24149
24150- 5.0.0
24151
24152Move `R.partialCurry` to Rambdax(reason for major bump).
24153
24154Use new type of export in Typescript definitions.
24155
24156Approve [PR #381](https://github.com/selfrefactor/rambda/pull/381) - add `R.applySpec`
24157
24158- 4.6.0
24159
24160Approve [PR #375](https://github.com/selfrefactor/rambda/pull/375) - add lenses(Thank you [@synthet1c](https://github.com/synthet1c))
24161
24162Add `R.lens`
24163
24164Add `R.lensIndex`
24165
24166Add `R.lensPath`
24167
24168Add `R.lensProp`
24169
24170Add `R.over`
24171
24172Add `R.set`
24173
24174Add `R.view`
24175
24176> Sync with Ramda 0.27
24177
24178Add `R.paths`
24179
24180Add `R.xor`
24181
24182> Close [Issue #373](https://github.com/selfrefactor/rambda/issues/373)
24183
24184Add `R.cond`
24185
24186- 4.5.0 Add `R.clamp`
24187
24188- 4.4.2 Improve `R.propOr` typings
24189
24190- 4.4.1 Make `R.reject` has the same typing as `R.filter`
24191
24192- 4.4.0 Several changes:
24193
24194Close [Issue #317](https://github.com/selfrefactor/rambda/issues/317) - add `R.transpose`
24195
24196Close [Issue #325](https://github.com/selfrefactor/rambda/issues/325) - `R.filter` should return equal values for bad inputs `null` and `undefined`
24197
24198Approve suggestion for `R.indexBy` to accept string not only function as first argument.
24199
24200Edit of `R.path` typings
24201
24202- 4.2.0 Approve [PR #314](https://github.com/selfrefactor/rambda/pull/314) - add `R.and`
24203
24204- 4.1.1 Add missing typings for `R.slice`
24205
24206- 4.1.0 Add `R.findLast` and `R.findLastIndex`
24207
24208- 4.0.2 Fix `R.isEmpty` wrong behaviour compared to the Ramda method
24209
24210- 4.0.1 Approve [PR #289](https://github.com/selfrefactor/rambda/pull/289) - remove console.log in `R.values` method
24211
24212- 4.0.0 Multiple breaking changes as Rambda methods are changed in order to increase the similarity between with Ramda
24213
24214Add to `Differences`:
24215
24216```text
24217R.type can return 'NaN'
24218
24219R.compose doesn't pass `this` context
24220
24221R.clone doesn't work with number, booleans and strings as input
24222```
24223
24224All breaking changes:
24225
24226-- R.add works only with numbers
24227
24228-- Fix R.adjust which had wrong order of arguments
24229
24230-- R.adjust works when index is out of bounds
24231
24232-- R.complement support function with multiple arguments
24233
24234-- R.compose/pipe throws when called with no argument
24235
24236-- R.clone works with `Date` value as input
24237
24238-- R.drop/dropLast/take/takeLast always return new copy of the list/string
24239
24240-- R.take/takeLast return original list/string with negative index
24241
24242-- R.equals handles `NaN` and `RegExp` types
24243
24244-- R.type/R.equals supports `new Boolean/new Number/new Date/new String` expressions
24245
24246-- R.has works with non-object
24247
24248-- R.ifElse pass all arguments
24249
24250-- R.length works with bad input
24251
24252-- R.propEq work with bad input for object argument
24253
24254-- R.range work with bad inputs
24255
24256-- R.times work with bad inputs
24257
24258-- R.reverse works with strings
24259
24260-- R.splitEvery throws on non-positive integer index
24261
24262-- R.test throws just like Ramda when first argument is not regex
24263
24264-- R.values works with bad inputs
24265
24266-- R.zipObj ignores extra keys
24267
24268- 3.3.0
24269
24270This is pre `4.0.0` release and it contains all of the above changes
24271
24272Close [issue #287](https://github.com/selfrefactor/rambda/issues/287) - `ts-toolbelt` directory was changed but not reflected in `files` property in `package.json`
24273
24274- 3.2.5
24275
24276Close [issue #273](https://github.com/selfrefactor/rambda/issues/273) - ts-toolbelt needs other type of export when `isolatedModules` TypeScript property
24277
24278Close [issue #245](https://github.com/selfrefactor/rambda/issues/245) - complete typings tests for methods that have more specific Typescript definitions
24279
24280- 3.2.1 Fast fix for [issue #273](https://github.com/selfrefactor/rambda/issues/273) - messed up typings
24281
24282- 3.2.0 There are several changes:
24283
24284Close [issue #263](https://github.com/selfrefactor/rambda/issues/263) - broken curry typing solved by `ts-toolbelt` local dependency.
24285
24286Add `R.partialCurry` typings.
24287
24288Approve [PR #266](https://github.com/selfrefactor/rambda/pull/266) that adds `R.slice` method.
24289
24290- 3.1.0 This might be breaking change for Typescript users, as very different definitions are introduced. With the previous state of the definitions, it was not possible to pass `dtslint` typings tests.
24291
24292- `R.either` and `R.both` supports multiple arguments as they should.
24293
24294- Several methods added by [@squidfunk](https://github.com/squidfunk) - `R.assocPath`, `R.symmetricDifference`, `R.intersperse`, `R.intersection` and `R.difference`
24295
24296- 3.0.1 Close [issue #234](https://github.com/selfrefactor/rambda/issues/234) - wrong curry typing
24297
24298- 3.0.0 Deprecate `R.contains`, while `R.includes` is now following Ramda API(it uses `R.equals` for comparision)
24299
24300- 2.14.5 `R.without` needs currying
24301
24302- 2.14.4 Close [issue #227](https://github.com/selfrefactor/rambda/issues/227) - add index as third argument of `R.reduce` typings
24303
24304- 2.14.2 Use `R.curry` with `R.reduce` as manual curry there didn't work as expected.
24305
24306- 2.14.1 Fix wrong typescript with `R.head` - [PR #228](https://github.com/selfrefactor/rambda/pull/228) pushed by [@tonivj5](https://github.com/tonivj5)
24307
24308- 2.14.0 Add `R.groupWith` by @selfrefactor | Add `R.propOr`, `R.mathMod`, `R.mean`, `R.median`, `R.negate`, `R.product` by [@ku8ar](https://github.com/ku8ar)
24309
24310- 2.13.0 Add `R.identical` - [PR #217](https://github.com/selfrefactor/rambda/pull/217) pushed by [@ku8ar](https://github.com/ku8ar)
24311
24312- 2.12.0 Add `R.propIs` - [PR #213](https://github.com/selfrefactor/rambda/pull/213) and add `R.sum` - [issue #207](https://github.com/selfrefactor/rambda/issues/207)
24313
24314- 2.11.2 Close Rambdax [issue #32](https://github.com/selfrefactor/rambdax/issues/32) - wrong `R.type` when function is input
24315
24316- 2.11.1 Approve [PR #182](https://github.com/selfrefactor/rambda/pull/182) - Changed typings to allow object as input to `R.forEach` and `R.map`
24317
24318- 2.11.0 Approve [PR #179](https://github.com/selfrefactor/rambda/pull/179) - `R.adjust` handles negative index; `R.all` doesn't need `R.filter`
24319
24320- 2.10.2 Close [issue #175](https://github.com/selfrefactor/rambda/issues/175) - missing typescript file
24321
24322- 2.10.0 Approve huge and important [PR #171](https://github.com/selfrefactor/rambda/pull/171) submitted by [@helmuthdu](https://github.com/helmuthdu) - Add comments to each method, improve Typescript support
24323
24324- 2.9.0 `R.toPairs` and `R.fromPairs`
24325
24326- 2.8.0 Approve [PR #165](https://github.com/selfrefactor/rambda/pull/165) `R.clone`
24327
24328- 2.7.1 expose `src` | Discussed at [issue #147](https://github.com/selfrefactor/rambda/issues/147)
24329
24330- 2.7.0 Approve [PR #161](https://github.com/selfrefactor/rambda/pull/161) `R.isEmpty`
24331
24332- 2.6.0 `R.map`, `R.filter` and `R.forEach` pass original object to iterator as third argument | Discussed at [issue #147](https://github.com/selfrefactor/rambda/issues/147)
24333
24334- 2.5.0 Close [issue #149](https://github.com/selfrefactor/rambda/issues/149) Add `R.partial` | `R.type` handles `NaN`
24335
24336- 2.4.0 Major bump of `Rollup`; Stop building for ES5
24337
24338- 2.3.1 Close [issue #90](https://github.com/selfrefactor/rambda/issues/90) | Add string type of path in `R.pathOr`
24339
24340- 2.3.0 Close [issue #89](https://github.com/selfrefactor/rambda/issues/89) | Fix missing `Number` TS definition in `R.type`
24341
24342- 2.2.0 `R.defaultTo` accepts indefinite number of input arguments. So the following is valid expression: `const x = defaultTo('foo',null, null, 'bar')`
24343
24344- 2.1.0 Restore `R.zip` using [WatermelonDB](https://github.com/Nozbe/WatermelonDB/) implementation.
24345
24346- 2.0.0 Major version caused by removing of `R.zip` and `R.addIndex`. [Issue #85](https://github.com/selfrefactor/rambda/issues/85) rightfully finds that the implementation of `R.addIndex` is not correct. This led to removing this method and also of `R.zip` as it had depended on it. The second change is that `R.map`, `R.filter` are passing array index as second argument when looping over arrays. The third change is that `R.includes` will return `false` if input is neigher `string` nor `array`. The previous behaviour was to throw an error. The last change is to increase the number of methods that are passing index as second argument to the predicate function.
24347
24348- 1.2.6 Use `src` folder instead of `modules`
24349- 1.2.5 Fix `omit` typing
24350- 1.2.4 Add missing Typescript definitions - [PR#82](https://github.com/selfrefactor/rambda/pull/82)
24351- 1.2.2 Change curry method used across most of library methods
24352- 1.2.1 Add `R.assoc` | fix passing `undefined` to `R.map` and `R.merge` [issue #77](https://github.com/selfrefactor/rambda/issues/77)
24353- 1.2.0 Add `R.min`, `R.minBy`, `R.max`, `R.maxBy`, `R.nth` and `R.keys`
24354- 1.1.5 Close [issue #74](https://github.com/selfrefactor/rambda/issues/74) `R.zipObj`
24355- 1.1.4 Close [issue #71](https://github.com/selfrefactor/rambda/issues/71) CRA fail to build `rambda`
24356- 1.1.3 Approve [PR #70](https://github.com/selfrefactor/rambda/pull/67) implement `R.groupBy` | Close [issue #69](https://github.com/selfrefactor/rambda/issues/69)
24357- 1.1.2 Approve [PR #67](https://github.com/selfrefactor/rambda/pull/67) use `babel-plugin-annotate-pure-calls`
24358- 1.1.1 Approve [PR #66](https://github.com/selfrefactor/rambda/pull/66) `R.zip`
24359- 1.1.0 `R.compose` accepts more than one input argument [issue #65](https://github.com/selfrefactor/rambda/issues/65)
24360- 1.0.13 Approve [PR #64](https://github.com/selfrefactor/rambda/pull/64) `R.indexOf`
24361- 1.0.12 Close [issue #61](https://github.com/selfrefactor/rambda/issues/61) make all functions modules
24362- 1.0.11 Close [issue #60](https://github.com/selfrefactor/rambda/issues/60) problem with babelrc
24363- 1.0.10 Close [issue #59](https://github.com/selfrefactor/rambda/issues/59) add R.dissoc
24364- 1.0.9 Close [issue #58](https://github.com/selfrefactor/rambda/issues/58) - Incorrect `R.equals`
24365- 1.0.8 `R.map` and `R.filter` pass object properties when mapping over objects
24366- 1.0.7 Add `R.uniqWith`
24367- 1.0.6 Close [issue #52](https://github.com/selfrefactor/rambda/issues/52) - ES5 compatible code
24368- 1.0.5 Close [issue #51](https://github.com/selfrefactor/rambda/issues/51)
24369- 1.0.4 Close [issue #50](https://github.com/selfrefactor/rambda/issues/50) - add `R.pipe` typings
24370- 1.0.3 `R.ifElse` accept also boolean as condition argument
24371- 1.0.2 Remove `typedDefaultTo` and `typedPathOr` | Add `R.pickAll` and `R.none`
24372- 1.0.0 Major change as build is now ES6 not ES5 compatible (Related to [issue #46](https://github.com/selfrefactor/rambda/issues/46))| Making `Rambda` fully tree-shakeable| Edit Typescript definition
24373- 0.9.8 Revert to ES5 compatible build - [issue #46](https://github.com/selfrefactor/rambda/issues/46)
24374- 0.9.7 Refactor for `Rollup` tree-shake | Remove `R.padEnd` and `R.padStart`
24375- 0.9.6 Close [issue #44](https://github.com/selfrefactor/rambda/issues/44) - `R.reverse` mutates the array
24376- 0.9.5 Close [issue #45](https://github.com/selfrefactor/rambda/issues/45) - invalid Typescript typings
24377- 0.9.4 Add `R.reject` and `R.without` ([PR#41](https://github.com/selfrefactor/rambda/pull/41) [PR#42](https://github.com/selfrefactor/rambda/pull/42)) | Remove 'browser' field in `package.json` due to Webpack bug [4674](https://github.com/webpack/webpack/issues/4674)
24378- 0.9.3 Add `R.forEach` and `R.times`
24379- 0.9.2 Add `Typescript` definitions
24380- 0.9.1 Close [issue #36](https://github.com/selfrefactor/rambda/issues/36) - move current behaviour of `defaultTo` to a new method `typedDefaultTo`; make `defaultTo` follow Ramda spec; add `pathOr`; add `typedPathOr`.
24381- 0.9.0 Add `R.pipe` [PR#35](https://github.com/selfrefactor/rambda/pull/35)
24382- 0.8.9 Add `R.isNil`
24383- 0.8.8 Migrate to ES modules [PR33](https://github.com/selfrefactor/rambda/pull/33) | Add R.flip to the API | R.map/filter works with objects
24384- 0.8.7 Change `Webpack` with `Rollup` - [PR29](https://github.com/selfrefactor/rambda/pull/29)
24385- 0.8.6 Add `R.tap` and `R.identity`
24386- 0.8.5 Add `R.all`, `R.allPass`, `R.both`, `R.either` and `R.complement`
24387- 0.8.4 Learning to run `yarn test` before `yarn publish` the hard way
24388- 0.8.3 Add `R.always`, `R.T` and `R.F`
24389- 0.8.2 Add `concat`, `padStart`, `padEnd`, `lastIndexOf`, `toString`, `reverse`, `endsWith` and `startsWith` methods
24390- 0.8.1 Add `R.ifElse`
24391- 0.8.0 Add `R.not`, `R.includes` | Take string as condition for `R.pick` and `R.omit`
24392- 0.7.6 Fix incorrect implementation of `R.values`
24393- 0.7.5 Fix incorrect implementation of `R.omit`
24394- 0.7.4 [issue #13](https://github.com/selfrefactor/rambda/issues/13) - Fix `R.curry`, which used to return incorrectly `function` when called with more arguments
24395- 0.7.3 Close [issue #9](https://github.com/selfrefactor/rambda/issues/9) - Compile to `es2015`; Approve [PR #10](https://github.com/selfrefactor/rambda/pull/10) - add `R.addIndex` to the API
24396- 0.7.2 Add `Promise` support for `R.type`
24397- 0.7.1 Close [issue #7](https://github.com/selfrefactor/rambda/issues/7) - add `R.reduce` to the API
24398- 0.7.0 Close [issue #5](https://github.com/selfrefactor/rambda/issues/5) - change name of `curry` to `partialCurry`; add new method `curry`, which works just like Ramda's `curry`
24399- 0.6.2 Add separate documentation site via `docsify`
24400
24401[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-changelog)
24402
24403## ➤ Additional info
24404
24405> Most influential contributors
24406
24407- [@farwayer](https://github.com/farwayer) - improving performance in R.find, R.filter; give the idea how to make benchmarks more reliable;
24408
24409- [@thejohnfreeman](https://github.com/thejohnfreeman) - add R.assoc, R.chain;
24410
24411- [@helmuthdu](https://github.com/helmuthdu) - add R.clone; help improve code style;
24412
24413- [@jpgorman](https://github.com/jpgorman) - add R.zip, R.reject, R.without, R.addIndex;
24414
24415- [@ku8ar](https://github.com/ku8ar) - add R.slice, R.propOr, R.identical, R.propIs and several math related methods; introduce the idea to display missing Ramda methods;
24416
24417- [@romgrk](https://github.com/romgrk) - add R.groupBy, R.indexBy, R.findLast, R.findLastIndex;
24418
24419- [@squidfunk](https://github.com/squidfunk) - add R.assocPath, R.symmetricDifference, R.difference, R.intersperse;
24420
24421- [@synthet1c](https://github.com/synthet1c) - add all lenses methods; add R.applySpec, R.converge;
24422
24423- [@vlad-zhukov](https://github.com/vlad-zhukov) - help with configuring Rollup, Babel; change export file to use ES module exports;
24424
24425> Rambda references
24426
24427- [Interview with Dejan Totef at SurviveJS blog](https://survivejs.com/blog/rambda-interview/)
24428
24429- [Awesome functional Javascript programming libraries](https://github.com/stoeffel/awesome-fp-js#libraries)
24430
24431> Links to Rambda
24432
24433- [https://mailchi.mp/webtoolsweekly/web-tools-280](Web Tools Weekly)
24434
24435- [https://github.com/stoeffel/awesome-fp-js](awesome-fp-js)
24436
24437- [https://github.com/docsifyjs/awesome-docsify](awesome-docsify)
24438
24439> Releases
24440
24441[Rambda's releases](https://github.com/selfrefactor/rambda/releases) are used mostly for testing purposes, so it is not advisable to be used.
24442
24443[![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#-additional-info)
24444
24445## My other libraries
24446
24447<table>
24448 <tbody>
24449 <tr valign="top">
24450 <td width="20%" align="center">
24451 <h4>Niketa theme</h4>
24452 <a href="https://marketplace.visualstudio.com/items?itemName=selfrefactor.Niketa-theme">Collection of 9 light VSCode themes</a>
24453 </td>
24454 <td width="20%" align="center">
24455 <h4>Niketa dark theme</h4>
24456 <a href="https://marketplace.visualstudio.com/items?itemName=selfrefactor.niketa-dark-theme">Collection of 9 dark VSCode themes</a>
24457 </td>
24458 <td width="20%" align="center">
24459 <h4>String-fn</h4>
24460 <a href="https://github.com/selfrefactor/services/tree/master/packages/string-fn">String utility library</a>
24461 </td>
24462 <td width="20%" align="center">
24463 <h4>Useful Javascript libraries</h4>
24464 <a href="https://github.com/selfrefactor/useful-javascript-libraries">Large collection of JavaScript,Typescript and Angular related repos links</a>
24465 </td>
24466 <td width="20%" align="center">
24467 <h4>Run-fn</h4>
24468 <a href="https://github.com/selfrefactor/services/tree/master/packages/run-fn">CLI commands for lint JS/TS files, commit git changes and upgrade of dependencies</a>
24469 </td>
24470 </tr>
24471 </tbody>
24472</table>
\No newline at end of file