rambda 10.3.4 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -565,7 +565,10 @@ describe('allPass', () => {
565
565
  [1, 2, 3, 4],
566
566
  [3, 4, 5],
567
567
  ]
568
- const result = R.pipe(list, R.map(R.allPass([R.includes(3), R.includes(4)])))
568
+ const result = R.pipe(list, R.map(R.allPass([
569
+ (x) => x.length > 2,
570
+ (x) => x.includes(3)
571
+ ])))
569
572
  result // $ExpectType boolean[]
570
573
  })
571
574
  })
@@ -828,7 +831,7 @@ describe('anyPass', () => {
828
831
 
829
832
  ```typescript
830
833
 
831
- append<T>(el: T): (list: T[]) => T[]
834
+ append<T>(el: T): (list: readonly T[]) => T[]
832
835
  ```
833
836
 
834
837
  It adds element `x` at the end of `iterable`.
@@ -845,8 +848,8 @@ const result = R.append('foo')(['bar', 'baz'])
845
848
  <summary>All TypeScript definitions</summary>
846
849
 
847
850
  ```typescript
848
- append<T>(el: T): (list: T[]) => T[];
849
851
  append<T>(el: T): (list: readonly T[]) => T[];
852
+ append<T>(el: T): (list: T[]) => T[];
850
853
  ```
851
854
 
852
855
  </details>
@@ -1989,6 +1992,105 @@ export function descend(getFunction) {
1989
1992
 
1990
1993
  [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#descend)
1991
1994
 
1995
+ ### difference
1996
+
1997
+ ```typescript
1998
+
1999
+ difference<T>(x: T[]): (y: T[]) => T[]
2000
+ ```
2001
+
2002
+ It returns a merged list of `x` and `y` with all equal elements removed.
2003
+
2004
+ `R.equals` is used to determine equality.
2005
+
2006
+ ```javascript
2007
+ const x = [ 1, 2, 3, 4 ]
2008
+ const y = [ 3, 4, 5, 6 ]
2009
+
2010
+ const result = R.difference(x)(y)
2011
+ // => [ 1, 2, 5, 6 ]
2012
+ ```
2013
+
2014
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?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%20R.difference(x)(y)%0A%2F%2F%20%3D%3E%20%5B%201%2C%202%2C%205%2C%206%20%5D">Try this <strong>R.difference</strong> example in Rambda REPL</a>
2015
+
2016
+ <details>
2017
+
2018
+ <summary>All TypeScript definitions</summary>
2019
+
2020
+ ```typescript
2021
+ difference<T>(x: T[]): (y: T[]) => T[];
2022
+ ```
2023
+
2024
+ </details>
2025
+
2026
+ <details>
2027
+
2028
+ <summary><strong>R.difference</strong> source</summary>
2029
+
2030
+ ```javascript
2031
+ import { filter } from './filter.js'
2032
+ import { includes } from './includes.js'
2033
+
2034
+ export function difference(x) {
2035
+ return y => ([
2036
+ ...filter(value => !includes(value)(y))(x),
2037
+ ...filter(value => !includes(value)(x))(y),
2038
+ ])
2039
+ }
2040
+ ```
2041
+
2042
+ </details>
2043
+
2044
+ <details>
2045
+
2046
+ <summary><strong>Tests</strong></summary>
2047
+
2048
+ ```javascript
2049
+ import { difference } from './difference.js'
2050
+
2051
+ test('difference', () => {
2052
+ const list1 = [1, 2, 3, 4]
2053
+ const list2 = [3, 4, 5, 6]
2054
+ expect(difference(list1)(list2)).toEqual([1, 2, 5, 6])
2055
+ expect(difference([])([])).toEqual([])
2056
+ })
2057
+
2058
+ test('difference with objects', () => {
2059
+ const list1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
2060
+ const list2 = [{ id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]
2061
+ expect(difference(list1)(list2)).toEqual([
2062
+ { id: 1 },
2063
+ { id: 2 },
2064
+ { id: 5 },
2065
+ { id: 6 },
2066
+ ])
2067
+ })
2068
+ ```
2069
+
2070
+ </details>
2071
+
2072
+ <details>
2073
+
2074
+ <summary><strong>TypeScript</strong> test</summary>
2075
+
2076
+ ```typescript
2077
+ import { difference } from 'rambda'
2078
+
2079
+ describe('R.difference', () => {
2080
+ it('happy', () => {
2081
+ const list1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
2082
+ const list2 = [{ id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]
2083
+ const result = difference(list1)(list2)
2084
+
2085
+ result // $ExpectType { id: number; }[]
2086
+ })
2087
+ })
2088
+ ```
2089
+
2090
+ </details>
2091
+
2092
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#difference)
2093
+
1992
2094
  ### drop
1993
2095
 
1994
2096
  ```typescript
@@ -3213,7 +3315,7 @@ it('R.evolve', () => {
3213
3315
 
3214
3316
  ```typescript
3215
3317
 
3216
- excludes<T extends string>(valueToFind: T): (input: string) => boolean
3318
+ excludes(list: readonly string[] | string): (substringToFind: string) => boolean
3217
3319
  ```
3218
3320
 
3219
3321
  Opposite of `R.includes`
@@ -3222,21 +3324,21 @@ Opposite of `R.includes`
3222
3324
 
3223
3325
  ```javascript
3224
3326
  const result = [
3225
- R.excludes('ar')('foo'),
3226
- R.excludes({a: 2})([{a: 1}])
3327
+ R.excludes('foo')('ar'),
3328
+ R.excludes([{a: 1}])({a: 2})
3227
3329
  ]
3228
3330
  // => [true, true ]
3229
3331
  ```
3230
3332
 
3231
- <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5B%0A%20%20R.excludes('ar')('foo')%2C%0A%20%20R.excludes(%7Ba%3A%202%7D)(%5B%7Ba%3A%201%7D%5D)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20true%20%5D">Try this <strong>R.excludes</strong> example in Rambda REPL</a>
3333
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5B%0A%20%20R.excludes('foo')('ar')%2C%0A%20%20R.excludes(%5B%7Ba%3A%201%7D%5D)(%7Ba%3A%202%7D)%0A%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20true%20%5D">Try this <strong>R.excludes</strong> example in Rambda REPL</a>
3232
3334
 
3233
3335
  <details>
3234
3336
 
3235
3337
  <summary>All TypeScript definitions</summary>
3236
3338
 
3237
3339
  ```typescript
3238
- excludes<T extends string>(valueToFind: T): (input: string) => boolean;
3239
- excludes<T>(valueToFind: T): (input: T[]) => boolean;
3340
+ excludes(list: readonly string[] | string): (substringToFind: string) => boolean;
3341
+ excludes<T>(list: readonly T[]): (target: T) => boolean;
3240
3342
  ```
3241
3343
 
3242
3344
  </details>
@@ -3289,7 +3391,7 @@ import { excludes, pipe } from 'rambda'
3289
3391
  describe('R.excludes', () => {
3290
3392
  it('happy', () => {
3291
3393
  const list = [{ a: { b: '1' } }, { a: { b: '2' } }, { a: { b: '3' } }]
3292
- const result = pipe(list, excludes({ a: { b: '1' } }))
3394
+ const result = pipe({ a: { b: '1' } }, excludes(list))
3293
3395
  result // $ExpectType boolean
3294
3396
  })
3295
3397
  it('with string', () => {
@@ -3303,6 +3405,96 @@ describe('R.excludes', () => {
3303
3405
 
3304
3406
  [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#excludes)
3305
3407
 
3408
+ ### exists
3409
+
3410
+ ```typescript
3411
+
3412
+ exists<T>(predicate: (x: T) => boolean): (list: T[]) => boolean
3413
+ ```
3414
+
3415
+ It returns `true` if there is at least one element in `list` that satisfy the `predicate`.
3416
+
3417
+ ```javascript
3418
+ const predicate = x => R.type(x.foo) === 'Number'
3419
+ const list = [{foo: 'bar'}, {foo: 1}]
3420
+
3421
+ const result = R.exists(predicate)(list)
3422
+ // => true
3423
+ ```
3424
+
3425
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?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.exists(predicate)(list)%0A%2F%2F%20%3D%3E%20true">Try this <strong>R.exists</strong> example in Rambda REPL</a>
3426
+
3427
+ <details>
3428
+
3429
+ <summary>All TypeScript definitions</summary>
3430
+
3431
+ ```typescript
3432
+ exists<T>(predicate: (x: T) => boolean): (list: T[]) => boolean;
3433
+ ```
3434
+
3435
+ </details>
3436
+
3437
+ <details>
3438
+
3439
+ <summary><strong>R.exists</strong> source</summary>
3440
+
3441
+ ```javascript
3442
+ import { find } from './find.js'
3443
+
3444
+ export function exists(predicate) {
3445
+ return list => {
3446
+ return find(predicate)(list) !== undefined
3447
+ }
3448
+ }
3449
+ ```
3450
+
3451
+ </details>
3452
+
3453
+ <details>
3454
+
3455
+ <summary><strong>Tests</strong></summary>
3456
+
3457
+ ```javascript
3458
+ import { exists } from './exists.js'
3459
+ import { propEq } from './propEq.js'
3460
+
3461
+ const list = [{ a: 1 }, { a: 2 }, { a: 3 }]
3462
+
3463
+ test('happy', () => {
3464
+ const fn = propEq(2, 'a')
3465
+ expect(exists(fn)(list)).toBe(true)
3466
+ })
3467
+
3468
+ test('nothing is found', () => {
3469
+ const fn = propEq(4, 'a')
3470
+ expect(exists(fn)(list)).toBe(false)
3471
+ })
3472
+ ```
3473
+
3474
+ </details>
3475
+
3476
+ <details>
3477
+
3478
+ <summary><strong>TypeScript</strong> test</summary>
3479
+
3480
+ ```typescript
3481
+ import { exists, pipe } from 'rambda'
3482
+
3483
+ const list = [1, 2, 3]
3484
+
3485
+ describe('R.exists', () => {
3486
+ it('happy', () => {
3487
+ const predicate = (x: number) => x > 2
3488
+ const result = pipe(list, exists(predicate))
3489
+ result // $ExpectType boolean
3490
+ })
3491
+ })
3492
+ ```
3493
+
3494
+ </details>
3495
+
3496
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#exists)
3497
+
3306
3498
  ### filter
3307
3499
 
3308
3500
  ```typescript
@@ -3333,10 +3525,10 @@ filter<T, S extends T>(
3333
3525
  ): (list: T[]) => S[];
3334
3526
  filter<T>(
3335
3527
  predicate: BooleanConstructor,
3336
- ): (list: readonly T[]) => StrictNonNullable<T>[];
3528
+ ): (list: readonly T[]) => ExcludeFalsy<T>[];
3337
3529
  filter<T>(
3338
3530
  predicate: BooleanConstructor,
3339
- ): (list: T[]) => StrictNonNullable<T>[];
3531
+ ): (list: T[]) => ExcludeFalsy<T>[];
3340
3532
  filter<T>(
3341
3533
  predicate: (value: T) => boolean,
3342
3534
  ): (list: T[]) => T[];
@@ -3400,20 +3592,45 @@ test('using Boolean', () => {
3400
3592
  <summary><strong>TypeScript</strong> test</summary>
3401
3593
 
3402
3594
  ```typescript
3403
- import { filter, pipe } from 'rambda'
3595
+ import { filter, includes, pipe, reject, sort, split, uniq } from 'rambda'
3404
3596
 
3405
3597
  const list = [1, 2, 3]
3406
3598
 
3407
3599
  describe('R.filter with array', () => {
3408
3600
  it('within pipe', () => {
3409
- const result = pipe(
3601
+ const _result = pipe(
3410
3602
  list,
3411
3603
  filter(x => {
3412
3604
  x // $ExpectType number
3413
3605
  return x > 1
3414
3606
  }),
3415
3607
  )
3416
- result // $ExpectType number[]
3608
+ _result // $ExpectType number[]
3609
+ })
3610
+
3611
+ it('complex example', () => {
3612
+ const text = `Dies ist ein einfacher Beispielsatz. Il fait beau aujourd'hui!`
3613
+ const language = 'de'
3614
+ const SENTENCE_END_CHARS = ['.', '!', '?', '।', '؟']
3615
+ const result = pipe(
3616
+ text,
3617
+ split(''),
3618
+ uniq,
3619
+ filter(char => {
3620
+ if (language === 'de') {
3621
+ return /[A-Za-zäßüöÜÖÄ]/g.test(char) === false
3622
+ }
3623
+ if (language === 'fr') {
3624
+ return /[A-Za-zÀÉàâçèéêîïôùû']/g.test(char) === false
3625
+ }
3626
+ throw new Error(`Language ${language} not supported`)
3627
+ }),
3628
+ sort((a, b) => (a === b ? 0 : a > b ? 1 : -1)),
3629
+ filter(char => char.trim().length > 0),
3630
+ reject(includes(SENTENCE_END_CHARS)),
3631
+ )
3632
+
3633
+ result // $ExpectType string[]
3417
3634
  })
3418
3635
  it('narrowing type', () => {
3419
3636
  interface Foo {
@@ -3422,17 +3639,15 @@ describe('R.filter with array', () => {
3422
3639
  interface Bar extends Foo {
3423
3640
  b: string
3424
3641
  }
3425
- type T = Foo | Bar
3426
- const testList: T[]= [{ a: 1 }, { a: 2 }, { a: 3 }]
3642
+ type T = Foo | Bar
3643
+ const testList: T[] = [{ a: 1 }, { a: 2 }, { a: 3 }]
3427
3644
  const filterBar = (x: T): x is Bar => {
3428
3645
  return typeof (x as Bar).b === 'string'
3429
3646
  }
3430
- const result = pipe(
3431
- testList,
3432
- filter(filterBar),
3433
- )
3434
- result // $ExpectType Bar[]
3647
+ const _result = pipe(testList, filter(filterBar))
3648
+ _result // $ExpectType Bar[]
3435
3649
  })
3650
+
3436
3651
  it('narrowing type - readonly', () => {
3437
3652
  interface Foo {
3438
3653
  a: number
@@ -3440,30 +3655,33 @@ describe('R.filter with array', () => {
3440
3655
  interface Bar extends Foo {
3441
3656
  b: string
3442
3657
  }
3443
- type T = Foo | Bar
3444
- const testList: T[]= [{ a: 1 }, { a: 2 }, { a: 3 }] as const
3658
+ type T = Foo | Bar
3659
+ const testList: T[] = [{ a: 1 }, { a: 2 }, { a: 3 }] as const
3445
3660
  const filterBar = (x: T): x is Bar => {
3446
3661
  return typeof (x as Bar).b === 'string'
3447
3662
  }
3448
- const result = pipe(
3449
- testList,
3450
- filter(filterBar),
3451
- )
3452
- result // $ExpectType Bar[]
3663
+ const _result = pipe(testList, filter(filterBar))
3664
+ _result // $ExpectType Bar[]
3453
3665
  })
3454
- it('filtering NonNullable', () => {
3455
- const testList = [1, 2, null, undefined, 3]
3456
- const result = pipe(testList, filter(Boolean))
3457
- result // $ExpectType number[]
3666
+
3667
+ it('filtering NonNullable - list of objects', () => {
3668
+ const testList = [{ a: 1 }, { a: 2 }, false, { a: 3 }]
3669
+ const _result = pipe(testList, filter(Boolean))
3670
+ _result // $ExpectType { a: number; }[]
3458
3671
  })
3672
+
3459
3673
  it('filtering NonNullable - readonly', () => {
3460
- const testList = [1, 2, null, undefined, 3] as const
3674
+ const testList = [1, 2, true, false, null, undefined, 3] as const
3461
3675
  const result = pipe(testList, filter(Boolean))
3462
3676
  result.includes(1)
3463
3677
  // @ts-expect-error
3678
+ result.includes(true)
3679
+ // @ts-expect-error
3680
+ result.includes(false)
3681
+ // @ts-expect-error
3464
3682
  result.includes(4)
3465
3683
  // @ts-expect-error
3466
- result.includes(undefined)
3684
+ result.includes(undefined)
3467
3685
  // @ts-expect-error
3468
3686
  result.includes(null)
3469
3687
  })
@@ -4780,7 +4998,7 @@ describe('R.head', () => {
4780
4998
 
4781
4999
  ```typescript
4782
5000
 
4783
- includes(s: string): (list: readonly string[] | string) => boolean
5001
+ includes<T>(list: readonly T[]): (target: T) => boolean
4784
5002
  ```
4785
5003
 
4786
5004
  If `input` is string, then this method work as native `String.includes`.
@@ -4789,21 +5007,21 @@ If `input` is array, then `R.equals` is used to define if `valueToFind` belongs
4789
5007
 
4790
5008
  ```javascript
4791
5009
  const result = [
4792
- R.includes('oo')('foo'),
4793
- R.includes({a: 1})([{a: 1}])
5010
+ R.includes('foo')('oo'),
5011
+ R.includes([{a: 1}])({a: 1})
4794
5012
  ]
4795
5013
  // => [true, true ]
4796
5014
  ```
4797
5015
 
4798
- <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5B%0A%20%20R.includes('oo')('foo')%2C%0A%20%20R.includes(%7Ba%3A%201%7D)(%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>
5016
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5B%0A%20%20R.includes('foo')('oo')%2C%0A%20%20R.includes(%5B%7Ba%3A%201%7D%5D)(%7Ba%3A%201%7D)%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>
4799
5017
 
4800
5018
  <details>
4801
5019
 
4802
5020
  <summary>All TypeScript definitions</summary>
4803
5021
 
4804
5022
  ```typescript
4805
- includes(s: string): (list: readonly string[] | string) => boolean;
4806
- includes<T>(target: T): (list: readonly T[]) => boolean;
5023
+ includes<T>(list: readonly T[]): (target: T) => boolean;
5024
+ includes(list: readonly string[] | string): (substringToFind: string) => boolean;
4807
5025
  ```
4808
5026
 
4809
5027
  </details>
@@ -4880,28 +5098,22 @@ test('with wrong input that does not throw', () => {
4880
5098
  <summary><strong>TypeScript</strong> test</summary>
4881
5099
 
4882
5100
  ```typescript
4883
- import { pipe, includes } from 'rambda'
5101
+ import { pipe , includes} from 'rambda'
4884
5102
 
4885
5103
  describe('R.includes', () => {
4886
5104
  it('happy', () => {
4887
5105
  const list = [{ a: { b: '1' } }, { a: { b: '2' } }, { a: { b: '3' } }]
4888
- const result = pipe(list, includes({ a: { b: '1' } }))
5106
+ const result = pipe({ a: { b: '1' } }, includes(list))
4889
5107
  result // $ExpectType boolean
4890
5108
  })
4891
5109
  it('with string', () => {
4892
- const result = pipe('foo', includes('bar'))
5110
+ const result = pipe('oo', includes('foo'))
4893
5111
  result // $ExpectType boolean
4894
5112
  })
4895
5113
  it('with array of strings', () => {
4896
- const result = pipe(['1','2'], includes('1'))
5114
+ const result = pipe('1', includes(['1','2','3']))
4897
5115
  result // $ExpectType boolean
4898
5116
  })
4899
- it('without R.pipe', () => {
4900
- const result1 = includes('1')(['1', '2'])
4901
- const result2 = includes(1)([1, 2])
4902
- result1 // $ExpectType boolean
4903
- result2 // $ExpectType boolean
4904
- })
4905
5117
  })
4906
5118
  ```
4907
5119
 
@@ -5215,130 +5427,6 @@ describe('R.init', () => {
5215
5427
 
5216
5428
  [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#init)
5217
5429
 
5218
- ### innerJoin
5219
-
5220
- ```typescript
5221
-
5222
- innerJoin<T1, T2>(
5223
- pred: (a: T1, b: T2) => boolean,
5224
- list1: T1[],
5225
- ): (list2: T2[]) => T1[]
5226
- ```
5227
-
5228
- It returns a new list by applying a `predicate` function to all elements of `list1` and `list2` and keeping only these elements where `predicate` returns `true`.
5229
-
5230
- ```javascript
5231
- const list1 = [1, 2, 3, 4, 5]
5232
- const list2 = [4, 5, 6]
5233
- const predicate = (x, y) => x >= y
5234
- const result = R.innerJoin(predicate, list1)(list2)
5235
- // => [4, 5]
5236
- ```
5237
-
5238
- <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20list1%20%3D%20%5B1%2C%202%2C%203%2C%204%2C%205%5D%0Aconst%20list2%20%3D%20%5B4%2C%205%2C%206%5D%0Aconst%20predicate%20%3D%20(x%2C%20y)%20%3D%3E%20x%20%3E%3D%20y%0Aconst%20result%20%3D%20R.innerJoin(predicate%2C%20list1)(list2)%0A%2F%2F%20%3D%3E%20%5B4%2C%205%5D">Try this <strong>R.innerJoin</strong> example in Rambda REPL</a>
5239
-
5240
- <details>
5241
-
5242
- <summary>All TypeScript definitions</summary>
5243
-
5244
- ```typescript
5245
- innerJoin<T1, T2>(
5246
- pred: (a: T1, b: T2) => boolean,
5247
- list1: T1[],
5248
- ): (list2: T2[]) => T1[];
5249
- ```
5250
-
5251
- </details>
5252
-
5253
- <details>
5254
-
5255
- <summary><strong>R.innerJoin</strong> source</summary>
5256
-
5257
- ```javascript
5258
- function _includesWith(pred, x, list) {
5259
- let idx = 0
5260
- const len = list.length
5261
-
5262
- while (idx < len) {
5263
- if (pred(x, list[idx])) {
5264
- return true
5265
- }
5266
-
5267
- idx += 1
5268
- }
5269
-
5270
- return false
5271
- }
5272
- function _filter(fn, list) {
5273
- let idx = 0
5274
- const len = list.length
5275
- const result = []
5276
-
5277
- while (idx < len) {
5278
- if (fn(list[idx])) {
5279
- result[result.length] = list[idx]
5280
- }
5281
-
5282
- idx += 1
5283
- }
5284
-
5285
- return result
5286
- }
5287
-
5288
- export function innerJoin(pred, xs) {
5289
- return ys => _filter(x => _includesWith(pred, x, ys), xs)
5290
- }
5291
- ```
5292
-
5293
- </details>
5294
-
5295
- <details>
5296
-
5297
- <summary><strong>Tests</strong></summary>
5298
-
5299
- ```javascript
5300
- import { innerJoin } from './innerJoin.js'
5301
-
5302
- const a = {
5303
- id: 1,
5304
- name: 'a',
5305
- }
5306
- const b = {
5307
- id: 2,
5308
- name: 'b',
5309
- }
5310
- const c = {
5311
- id: 3,
5312
- name: 'c',
5313
- }
5314
- const f = (a, b) => innerJoin((r, id) => r.id === id, a)(b)
5315
-
5316
- test('only returns elements from the first list', () => {
5317
- expect(f([a, b, c], [])).toEqual([])
5318
- expect(f([a, b, c], [1])).toEqual([a])
5319
- expect(f([a, b, c], [1, 2])).toEqual([a, b])
5320
- expect(f([a, b, c], [1, 2, 3])).toEqual([a, b, c])
5321
- expect(f([a, b, c], [1, 2, 3, 4])).toEqual([a, b, c])
5322
- })
5323
-
5324
- test('does not remove duplicates', () => {
5325
- expect(f([a, a, a], [1, 2, 3])).toEqual([a, a, a])
5326
- expect(f([a, b, c], [1, 1, 1])).toEqual([a])
5327
- })
5328
-
5329
- test('readme example', () => {
5330
- const list1 = [1, 2, 3, 4, 5]
5331
- const list2 = [4, 5, 6]
5332
- const predicate = (x, y) => x >= y
5333
- const result = innerJoin(predicate, list1)(list2)
5334
- expect(result).toEqual([4, 5])
5335
- })
5336
- ```
5337
-
5338
- </details>
5339
-
5340
- [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#innerJoin)
5341
-
5342
5430
  ### interpolate
5343
5431
 
5344
5432
  ```typescript
@@ -5439,55 +5527,182 @@ const templateArguments = { x: 'led zeppelin' }
5439
5527
  it('R.interpolate', () => {
5440
5528
  const result = interpolate(templateInput)(templateArguments)
5441
5529
 
5442
- result // $ExpectType string
5530
+ result // $ExpectType string
5531
+ })
5532
+ ```
5533
+
5534
+ </details>
5535
+
5536
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#interpolate)
5537
+
5538
+ ### intersection
5539
+
5540
+ ```typescript
5541
+
5542
+ intersection<T>(listA: T[]): (listB: T[]) => T[]
5543
+ ```
5544
+
5545
+ It loops through `listA` and `listB` and returns the intersection of the two according to `R.equals`.
5546
+
5547
+ ```javascript
5548
+ const listA = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
5549
+ const listB = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
5550
+
5551
+ const result = R.intersection(listA)(listB)
5552
+ // => [{ id : 3 }, { id : 4 }]
5553
+ ```
5554
+
5555
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?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%20R.intersection(listA)(listB)%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>
5556
+
5557
+ <details>
5558
+
5559
+ <summary>All TypeScript definitions</summary>
5560
+
5561
+ ```typescript
5562
+ intersection<T>(listA: T[]): (listB: T[]) => T[];
5563
+ ```
5564
+
5565
+ </details>
5566
+
5567
+ <details>
5568
+
5569
+ <summary><strong>R.intersection</strong> source</summary>
5570
+
5571
+ ```javascript
5572
+ import { filter } from './filter.js'
5573
+ import { includes } from './includes.js'
5574
+
5575
+ export function intersection(listA) {
5576
+ return listB => filter(x => includes(x)(listA))(listB)
5577
+ }
5578
+ ```
5579
+
5580
+ </details>
5581
+
5582
+ <details>
5583
+
5584
+ <summary><strong>Tests</strong></summary>
5585
+
5586
+ ```javascript
5587
+ import { intersection } from './intersection.js'
5588
+
5589
+ test('intersection', () => {
5590
+ const list1 = [1, 2, 3, 4]
5591
+ const list2 = [3, 4, 5, 6]
5592
+ expect(intersection(list1)(list2)).toEqual([3, 4])
5593
+ expect(intersection([])([])).toEqual([])
5594
+ })
5595
+
5596
+ test('intersection with objects', () => {
5597
+ const list1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
5598
+ const list2 = [{ id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]
5599
+ expect(intersection(list1)(list2)).toEqual([{ id: 3 }, { id: 4 }])
5600
+ })
5601
+
5602
+ test('order is the same as in Ramda', () => {
5603
+ const list = ['a', 'b', 'c', 'd']
5604
+
5605
+ expect(intersection(list)(['b', 'c'])).toEqual(['b', 'c'])
5606
+ expect(intersection(list)(['c', 'b'])).toEqual(['c', 'b'])
5607
+ })
5608
+ ```
5609
+
5610
+ </details>
5611
+
5612
+ <details>
5613
+
5614
+ <summary><strong>TypeScript</strong> test</summary>
5615
+
5616
+ ```typescript
5617
+ import { intersection } from 'rambda'
5618
+
5619
+ const list1 = [1, 2, 3]
5620
+ const list2 = [1, 3, 5]
5621
+
5622
+ describe('R.intersection', () => {
5623
+ it('happy', () => {
5624
+ const result = intersection(list1)(list2)
5625
+ result // $ExpectType number[]
5626
+ })
5443
5627
  })
5444
5628
  ```
5445
5629
 
5446
5630
  </details>
5447
5631
 
5448
- [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#interpolate)
5632
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#intersection)
5449
5633
 
5450
- ### intersection
5634
+ ### intersectionWith
5451
5635
 
5452
5636
  ```typescript
5453
5637
 
5454
- intersection<T>(listA: T[]): (listB: T[]) => T[]
5638
+ intersectionWith<T1, T2>(
5639
+ pred: (a: T1, b: T2) => boolean,
5640
+ list1: T1[],
5641
+ ): (list2: T2[]) => T1[]
5455
5642
  ```
5456
5643
 
5457
- It loops through `listA` and `listB` and returns the intersection of the two according to `R.equals`.
5458
-
5459
- > :boom: There is slight difference between Rambda and Ramda implementation. Ramda.intersection(['a', 'b', 'c'], ['c', 'b']) result is "[ 'c', 'b' ]", but Rambda result is "[ 'b', 'c' ]".
5644
+ It returns a new list by applying a `predicate` function to all elements of `list1` and `list2` and keeping only these elements where `predicate` returns `true`.
5460
5645
 
5461
5646
  ```javascript
5462
- const listA = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 4 } ]
5463
- const listB = [ { id : 3 }, { id : 4 }, { id : 5 }, { id : 6 } ]
5464
-
5465
- const result = R.intersection(listA)(listB)
5466
- // => [{ id : 3 }, { id : 4 }]
5647
+ const list1 = [1, 2, 3, 4, 5]
5648
+ const list2 = [4, 5, 6]
5649
+ const predicate = (x, y) => x >= y
5650
+ const result = R.intersectionWith(predicate, list1)(list2)
5651
+ // => [4, 5]
5467
5652
  ```
5468
5653
 
5469
- <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?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%20R.intersection(listA)(listB)%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>
5654
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20list1%20%3D%20%5B1%2C%202%2C%203%2C%204%2C%205%5D%0Aconst%20list2%20%3D%20%5B4%2C%205%2C%206%5D%0Aconst%20predicate%20%3D%20(x%2C%20y)%20%3D%3E%20x%20%3E%3D%20y%0Aconst%20result%20%3D%20R.intersectionWith(predicate%2C%20list1)(list2)%0A%2F%2F%20%3D%3E%20%5B4%2C%205%5D">Try this <strong>R.intersectionWith</strong> example in Rambda REPL</a>
5470
5655
 
5471
5656
  <details>
5472
5657
 
5473
5658
  <summary>All TypeScript definitions</summary>
5474
5659
 
5475
5660
  ```typescript
5476
- intersection<T>(listA: T[]): (listB: T[]) => T[];
5661
+ intersectionWith<T1, T2>(
5662
+ pred: (a: T1, b: T2) => boolean,
5663
+ list1: T1[],
5664
+ ): (list2: T2[]) => T1[];
5477
5665
  ```
5478
5666
 
5479
5667
  </details>
5480
5668
 
5481
5669
  <details>
5482
5670
 
5483
- <summary><strong>R.intersection</strong> source</summary>
5671
+ <summary><strong>R.intersectionWith</strong> source</summary>
5484
5672
 
5485
5673
  ```javascript
5486
- import { filter } from './filter.js'
5487
- import { includes } from './includes.js'
5674
+ function _includesWith(pred, x, list) {
5675
+ let idx = 0
5676
+ const len = list.length
5488
5677
 
5489
- export function intersection(listA) {
5490
- return listB => filter(x => includes(x)(listA))(listB)
5678
+ while (idx < len) {
5679
+ if (pred(x, list[idx])) {
5680
+ return true
5681
+ }
5682
+
5683
+ idx += 1
5684
+ }
5685
+
5686
+ return false
5687
+ }
5688
+ function _filter(fn, list) {
5689
+ let idx = 0
5690
+ const len = list.length
5691
+ const result = []
5692
+
5693
+ while (idx < len) {
5694
+ if (fn(list[idx])) {
5695
+ result[result.length] = list[idx]
5696
+ }
5697
+
5698
+ idx += 1
5699
+ }
5700
+
5701
+ return result
5702
+ }
5703
+
5704
+ export function intersectionWith(pred, xs) {
5705
+ return ys => _filter(x => _includesWith(pred, x, ys), xs)
5491
5706
  }
5492
5707
  ```
5493
5708
 
@@ -5498,26 +5713,41 @@ export function intersection(listA) {
5498
5713
  <summary><strong>Tests</strong></summary>
5499
5714
 
5500
5715
  ```javascript
5501
- import { intersection } from './intersection.js'
5716
+ import { intersectionWith } from './intersectionWith.js'
5502
5717
 
5503
- test('intersection', () => {
5504
- const list1 = [1, 2, 3, 4]
5505
- const list2 = [3, 4, 5, 6]
5506
- expect(intersection(list1)(list2)).toEqual([3, 4])
5507
- expect(intersection([])([])).toEqual([])
5508
- })
5718
+ const a = {
5719
+ id: 1,
5720
+ name: 'a',
5721
+ }
5722
+ const b = {
5723
+ id: 2,
5724
+ name: 'b',
5725
+ }
5726
+ const c = {
5727
+ id: 3,
5728
+ name: 'c',
5729
+ }
5730
+ const f = (a, b) => intersectionWith((r, id) => r.id === id, a)(b)
5509
5731
 
5510
- test('intersection with objects', () => {
5511
- const list1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
5512
- const list2 = [{ id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]
5513
- expect(intersection(list1)(list2)).toEqual([{ id: 3 }, { id: 4 }])
5732
+ test('only returns elements from the first list', () => {
5733
+ expect(f([a, b, c], [])).toEqual([])
5734
+ expect(f([a, b, c], [1])).toEqual([a])
5735
+ expect(f([a, b, c], [1, 2])).toEqual([a, b])
5736
+ expect(f([a, b, c], [1, 2, 3])).toEqual([a, b, c])
5737
+ expect(f([a, b, c], [1, 2, 3, 4])).toEqual([a, b, c])
5514
5738
  })
5515
5739
 
5516
- test('order is the same as in Ramda', () => {
5517
- const list = ['a', 'b', 'c', 'd']
5740
+ test('does not remove duplicates', () => {
5741
+ expect(f([a, a, a], [1, 2, 3])).toEqual([a, a, a])
5742
+ expect(f([a, b, c], [1, 1, 1])).toEqual([a])
5743
+ })
5518
5744
 
5519
- expect(intersection(list)(['b', 'c'])).toEqual(['b', 'c'])
5520
- expect(intersection(list)(['c', 'b'])).toEqual(['c', 'b'])
5745
+ test('readme example', () => {
5746
+ const list1 = [1, 2, 3, 4, 5]
5747
+ const list2 = [4, 5, 6]
5748
+ const predicate = (x, y) => x >= y
5749
+ const result = intersectionWith(predicate, list1)(list2)
5750
+ expect(result).toEqual([4, 5])
5521
5751
  })
5522
5752
  ```
5523
5753
 
@@ -5528,14 +5758,17 @@ test('order is the same as in Ramda', () => {
5528
5758
  <summary><strong>TypeScript</strong> test</summary>
5529
5759
 
5530
5760
  ```typescript
5531
- import { intersection } from 'rambda'
5761
+ import { intersectionWith, pipe } from 'rambda'
5532
5762
 
5533
5763
  const list1 = [1, 2, 3]
5534
5764
  const list2 = [1, 3, 5]
5535
5765
 
5536
- describe('R.intersection', () => {
5766
+ describe('R.intersectionWith', () => {
5537
5767
  it('happy', () => {
5538
- const result = intersection(list1)(list2)
5768
+ const result = pipe(
5769
+ list1,
5770
+ intersectionWith((x, y) => x === y, list2),
5771
+ )
5539
5772
  result // $ExpectType number[]
5540
5773
  })
5541
5774
  })
@@ -5543,7 +5776,7 @@ describe('R.intersection', () => {
5543
5776
 
5544
5777
  </details>
5545
5778
 
5546
- [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#intersection)
5779
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#intersectionWith)
5547
5780
 
5548
5781
  ### intersperse
5549
5782
 
@@ -9633,25 +9866,25 @@ describe('R.propSatisfies', () => {
9633
9866
 
9634
9867
  ```typescript
9635
9868
 
9636
- range(startInclusive: number): (endExclusive: number) => number[]
9869
+ range(endInclusive: number) : number[]
9637
9870
  ```
9638
9871
 
9639
- It returns list of numbers between `startInclusive` to `endExclusive` markers.
9640
- If `start` is greater than `end`, then the result will be in descending order.
9872
+ It returns list of numbers between `startInclusive` to `endInclusive` markers.
9641
9873
 
9642
9874
  ```javascript
9643
- [R.range(0)(5), R.range(5)(0)]
9644
- // => [[0, 1, 2, 3, 4], [5, 4, 3, 2, 1]]
9875
+ [R.range(5), R.range(1, 5)]
9876
+ // => [[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
9645
9877
  ```
9646
9878
 
9647
- <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5BR.range(0)(5)%2C%20R.range(5)(0)%5D%0A%2F%2F%20%3D%3E%20%5B%5B0%2C%201%2C%202%2C%203%2C%204%5D%2C%20%5B5%2C%204%2C%203%2C%202%2C%201%5D%5D">Try this <strong>R.range</strong> example in Rambda REPL</a>
9879
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20%5BR.range(5)%2C%20R.range(1%2C%205)%5D%0A%2F%2F%20%3D%3E%20%5B%5B0%2C%201%2C%202%2C%203%2C%204%2C%205%5D%2C%20%5B1%2C%202%2C%203%2C%204%2C%205%5D%5D">Try this <strong>R.range</strong> example in Rambda REPL</a>
9648
9880
 
9649
9881
  <details>
9650
9882
 
9651
9883
  <summary>All TypeScript definitions</summary>
9652
9884
 
9653
9885
  ```typescript
9654
- range(startInclusive: number): (endExclusive: number) => number[];
9886
+ range(endInclusive: number) : number[];
9887
+ range(startInclusive: number, endInclusive: number) : number[];
9655
9888
  ```
9656
9889
 
9657
9890
  </details>
@@ -9661,37 +9894,14 @@ range(startInclusive: number): (endExclusive: number) => number[];
9661
9894
  <summary><strong>R.range</strong> source</summary>
9662
9895
 
9663
9896
  ```javascript
9664
- function rangeDescending(start, end) {
9665
- const len = start - end
9666
- const willReturn = Array(len)
9667
-
9668
- for (let i = 0; i < len; i++) {
9669
- willReturn[i] = start - i
9670
- }
9671
-
9672
- return willReturn
9673
- }
9674
-
9675
- export function range(start) {
9676
- return end => {
9677
- if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))) {
9678
- throw new TypeError('Both arguments to range must be numbers')
9679
- }
9680
-
9681
- if (end === start) {
9682
- return []
9683
- }
9684
- if (end < start) return rangeDescending(start,end)
9685
-
9686
- const len = end - start
9687
- const willReturn = Array(len)
9688
-
9689
- for (let i = 0; i < len; i++) {
9690
- willReturn[i] = start + i
9691
- }
9692
-
9693
- return willReturn
9897
+ export function range(a, b) {
9898
+ const start = b === undefined ? 0 : a
9899
+ const end = b === undefined ? a : b
9900
+ if (end<= start) {
9901
+ return []
9694
9902
  }
9903
+ const len = end - start
9904
+ return Array.from({ length: len + 1 }, (_, i) => start + i)
9695
9905
  }
9696
9906
  ```
9697
9907
 
@@ -9705,9 +9915,10 @@ export function range(start) {
9705
9915
  import { range } from './range.js'
9706
9916
 
9707
9917
  test('happy', () => {
9708
- expect(range(0)(5)).toEqual([0, 1, 2, 3, 4])
9709
- expect(range(7)(3)).toEqual([7, 6, 5, 4])
9710
- expect(range(5)(5)).toEqual([])
9918
+ expect(range(5)).toEqual([0, 1, 2, 3, 4, 5])
9919
+ expect(range(3,5)).toEqual([3, 4, 5])
9920
+ expect(range(5,3)).toEqual([])
9921
+ expect(range(0)).toEqual([])
9711
9922
  })
9712
9923
  ```
9713
9924
 
@@ -9722,9 +9933,9 @@ import { range } from 'rambda'
9722
9933
 
9723
9934
  describe('R.range', () => {
9724
9935
  it('curried', () => {
9725
- const result = range(1)(4)
9936
+ const result = [range(1, 4), range(1)]
9726
9937
 
9727
- result // $ExpectType number[]
9938
+ result // $ExpectType number[][]
9728
9939
  })
9729
9940
  })
9730
9941
  ```
@@ -9733,6 +9944,62 @@ describe('R.range', () => {
9733
9944
 
9734
9945
  [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#range)
9735
9946
 
9947
+ ### rangeDescending
9948
+
9949
+ ```typescript
9950
+
9951
+ rangeDescending(startInclusive: number, endInclusive: number) : number[]
9952
+ ```
9953
+
9954
+ It returns list of numbers between `endInclusive` to `startInclusive` markers.
9955
+
9956
+ <details>
9957
+
9958
+ <summary>All TypeScript definitions</summary>
9959
+
9960
+ ```typescript
9961
+ rangeDescending(startInclusive: number, endInclusive: number) : number[];
9962
+ rangeDescending(endInclusive: number) : number[];
9963
+ ```
9964
+
9965
+ </details>
9966
+
9967
+ <details>
9968
+
9969
+ <summary><strong>R.rangeDescending</strong> source</summary>
9970
+
9971
+ ```javascript
9972
+ export function rangeDescending(start, b) {
9973
+ const end = b === undefined ? 0 : b
9974
+ if (start <= end) {
9975
+ return []
9976
+ }
9977
+ const len = start - end
9978
+ return Array.from({ length: len + 1 }, (_, i) => start - i)
9979
+ }
9980
+ ```
9981
+
9982
+ </details>
9983
+
9984
+ <details>
9985
+
9986
+ <summary><strong>Tests</strong></summary>
9987
+
9988
+ ```javascript
9989
+ import { rangeDescending } from './rangeDescending.js'
9990
+
9991
+ test('happy', () => {
9992
+ expect(rangeDescending(5)).toEqual([5, 4, 3, 2, 1, 0])
9993
+ expect(rangeDescending(7,3)).toEqual([7, 6, 5, 4,3])
9994
+ expect(rangeDescending(5, 7)).toEqual([])
9995
+ expect(rangeDescending(5, 5)).toEqual([])
9996
+ })
9997
+ ```
9998
+
9999
+ </details>
10000
+
10001
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#rangeDescending)
10002
+
9736
10003
  ### reduce
9737
10004
 
9738
10005
  ```typescript
@@ -11338,10 +11605,10 @@ describe('R.splitEvery', () => {
11338
11605
 
11339
11606
  ```typescript
11340
11607
 
11341
- symmetricDifference<T>(x: T[]): <T>(y: T[]) => T[]
11608
+ symmetricDifference<T>(x: T[]): (y: T[]) => T[]
11342
11609
  ```
11343
11610
 
11344
- It returns a merged list of `x` and `y` with all equal elements removed.
11611
+ It returns all items that are in either of the lists, but not in both.
11345
11612
 
11346
11613
  `R.equals` is used to determine equality.
11347
11614
 
@@ -11360,7 +11627,7 @@ const result = R.symmetricDifference(x)(y)
11360
11627
  <summary>All TypeScript definitions</summary>
11361
11628
 
11362
11629
  ```typescript
11363
- symmetricDifference<T>(x: T[]): <T>(y: T[]) => T[];
11630
+ symmetricDifference<T>(x: T[]): (y: T[]) => T[];
11364
11631
  ```
11365
11632
 
11366
11633
  </details>
@@ -11558,8 +11825,8 @@ const result = [
11558
11825
  ```typescript
11559
11826
  take<T>(howMany: number): {
11560
11827
  (input: string): string;
11561
- (input: T[]): T[];
11562
11828
  (input: readonly T[]): T[];
11829
+ (input: T[]): T[];
11563
11830
  };
11564
11831
  ...
11565
11832
  ...
@@ -11651,8 +11918,8 @@ const result = [
11651
11918
  ```typescript
11652
11919
  takeLast<T>(howMany: number): {
11653
11920
  (input: string): string;
11654
- (input: T[]): T[];
11655
11921
  (input: readonly T[]): T[];
11922
+ (input: T[]): T[];
11656
11923
  };
11657
11924
  ...
11658
11925
  ...
@@ -12584,6 +12851,105 @@ describe('R.union', () => {
12584
12851
 
12585
12852
  [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#union)
12586
12853
 
12854
+ ### unionWith
12855
+
12856
+ ```typescript
12857
+
12858
+ unionWith<T>(predicate: (x: T, y: T) => boolean, x: T[]): (y: T[]) => T[]
12859
+ ```
12860
+
12861
+ ```javascript
12862
+ const result = R.pipe(
12863
+ [{a: 1, b: 1}, {a: 2, b: 1}],
12864
+ R.unionWith((x, y) => x === y, [{a: 2, b: 2}, {a: 3, b: 2}]),
12865
+ )
12866
+ // => [{a: 1, b: 1}, {a: 2, b: 1}, {a: 3, b: 2}]
12867
+ ```
12868
+
12869
+ <a title="redirect to Rambda Repl site" href="https://rambda.netlify.app?const%20result%20%3D%20R.pipe(%0A%09%5B%7Ba%3A%201%2C%20b%3A%201%7D%2C%20%7Ba%3A%202%2C%20b%3A%201%7D%5D%2C%0A%09R.unionWith((x%2C%20y)%20%3D%3E%20x%20%3D%3D%3D%20y%2C%20%5B%7Ba%3A%202%2C%20b%3A%202%7D%2C%20%7Ba%3A%203%2C%20b%3A%202%7D%5D)%2C%0A)%0A%2F%2F%20%3D%3E%20%5B%7Ba%3A%201%2C%20b%3A%201%7D%2C%20%7Ba%3A%202%2C%20b%3A%201%7D%2C%20%7Ba%3A%203%2C%20b%3A%202%7D%5D">Try this <strong>R.unionWith</strong> example in Rambda REPL</a>
12870
+
12871
+ <details>
12872
+
12873
+ <summary>All TypeScript definitions</summary>
12874
+
12875
+ ```typescript
12876
+ unionWith<T>(predicate: (x: T, y: T) => boolean, x: T[]): (y: T[]) => T[];
12877
+ ```
12878
+
12879
+ </details>
12880
+
12881
+ <details>
12882
+
12883
+ <summary><strong>R.unionWith</strong> source</summary>
12884
+
12885
+ ```javascript
12886
+ export function unionWith(predicate, x) {
12887
+ return y => {
12888
+ const filtered = y.filter(yInstance => {
12889
+ return x.every(xInstance => {
12890
+ return !predicate(xInstance, yInstance)
12891
+ })
12892
+ })
12893
+
12894
+ return [...x, ...filtered]
12895
+ }
12896
+ }
12897
+ ```
12898
+
12899
+ </details>
12900
+
12901
+ <details>
12902
+
12903
+ <summary><strong>Tests</strong></summary>
12904
+
12905
+ ```javascript
12906
+ import { unionWith } from './unionWith.js'
12907
+ import { pipe } from './pipe.js'
12908
+
12909
+ test('happy', () => {
12910
+ const list1 = [{a: 1, b: 1}, {a: 2, b: 1}]
12911
+ const list2 = [{a: 2, b: 2}, {a: 3, b: 2}]
12912
+ const result = pipe(
12913
+ list2,
12914
+ unionWith((x, y) => {
12915
+ return x.a === y.a
12916
+ }, list1),
12917
+ )
12918
+ expect(result).toEqual([{a: 1, b: 1}, {a: 2, b: 1}, {a: 3, b: 2}])
12919
+ })
12920
+ ```
12921
+
12922
+ </details>
12923
+
12924
+ <details>
12925
+
12926
+ <summary><strong>TypeScript</strong> test</summary>
12927
+
12928
+ ```typescript
12929
+ import { pipe, unionWith } from 'rambda'
12930
+
12931
+ describe('R.unionWith', () => {
12932
+ it('happy', () => {
12933
+ const list = [{a: 1, b: 1}, {a: 2, b: 1}]
12934
+ const result = pipe(
12935
+ list,
12936
+ unionWith((x, y) => {
12937
+ x.a // $ExpectType number
12938
+ y.b // $ExpectType number
12939
+ return x.a === y.a
12940
+ }, [{a: 2, b: 2}, {a: 3, b: 2}]),
12941
+ )
12942
+
12943
+ result[0].a // $ExpectType number
12944
+ result[0].b // $ExpectType number
12945
+ })
12946
+ })
12947
+ ```
12948
+
12949
+ </details>
12950
+
12951
+ [![---------------](https://raw.githubusercontent.com/selfrefactor/rambda/master/files/separator.png)](#unionWith)
12952
+
12587
12953
  ### uniq
12588
12954
 
12589
12955
  ```typescript
@@ -13616,6 +13982,30 @@ describe('R.zipWith', () => {
13616
13982
 
13617
13983
  ## ❯ CHANGELOG
13618
13984
 
13985
+ 11.0.0
13986
+
13987
+ - Breaking change: `R.includes` and `R.excludes` now accept list as first argument and value to search as second argument. This makes it more useful when used with `R.filter` and `R.reject`.
13988
+
13989
+ - Rename `R.innerJoin` to `R.intersectionWith`
13990
+
13991
+ - Add `R.unionWith`
13992
+
13993
+ - Add `R.exists`
13994
+
13995
+ - Add `R.symmetricDifference`
13996
+
13997
+ - Add `R.difference`
13998
+
13999
+ - `R.range` now works similar to Ruby's `Range` - both start and end values are inclusive.
14000
+
14001
+ - Add `R.rangeDescending` as now `R.range` works only in ascending order.
14002
+
14003
+ - `R.range` - it accepts one or two arguments. If one argument is passed, it is considered as end value, and start is 0.
14004
+
14005
+ - R.rangeDescending - it accepts one or two arguments. If one argument is passed, it is considered as start value, and end is 0.
14006
+
14007
+ - Fix `R.filter(Boolean)` to handle filter of `false`, not only nullable values.
14008
+
13619
14009
  10.3.4
13620
14010
 
13621
14011
  - Fix wrong typing for `R.sortByDescending` - [Issue #797](https://github.com/selfrefactor/rambda/issues/797)
@@ -13624,6 +14014,10 @@ describe('R.zipWith', () => {
13624
14014
 
13625
14015
  - Change order of inputs in `R.mapPropObject`
13626
14016
 
14017
+ - Change REPL links in documentation
14018
+
14019
+ - Remove `jsr.json`
14020
+
13627
14021
  10.3.3
13628
14022
 
13629
14023
  - Fix wrong typing for `R.reject` - [Issue #779](https://github.com/selfrefactor/rambda/issues/779)