rambda 8.3.0 → 8.5.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/CHANGELOG.md +38 -0
- package/README.md +510 -350
- package/dist/rambda.js +246 -207
- package/dist/rambda.umd.js +1 -1
- package/immutable.d.ts +62 -17
- package/index.d.ts +62 -17
- package/package.json +107 -106
- package/rambda.js +5 -0
- package/src/_internals/compare.js +3 -0
- package/src/_internals/createPath.js +5 -1
- package/src/_internals/createPathInput.js +7 -0
- package/src/_internals/includes.js +12 -0
- package/src/_internals/isInteger.js +5 -0
- package/src/assoc.js +1 -1
- package/src/assocPath.js +9 -13
- package/src/dissocPath.js +47 -0
- package/src/dropRepeatsBy.js +21 -0
- package/src/empty.js +15 -0
- package/src/eqBy.js +10 -0
- package/src/equals.js +40 -52
- package/src/forEach.js +30 -20
- package/src/mergeWith.js +5 -11
- package/src/omit.js +4 -6
- package/src/partial.js +9 -3
- package/src/removeIndex.js +7 -0
package/README.md
CHANGED
|
@@ -51,13 +51,17 @@ import {add} from 'rambda/immutable'
|
|
|
51
51
|
|
|
52
52
|
### Deno support
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Latest version of **Ramba** available for `Deno` users is 3 years old. This is not the case with **Rambda** as most of recent releases are available for `Deno` users.
|
|
55
|
+
|
|
56
|
+
Also, `Rambda` provides you with included TS definitions:
|
|
55
57
|
|
|
56
58
|
```
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
// Deno extension(https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno)
|
|
60
|
+
// is installed and initialized
|
|
61
|
+
import * as R from "https://deno.land/x/rambda/mod.ts";
|
|
62
|
+
import * as Ramda from "https://x.nest.land/ramda@0.27.2/mod.ts";
|
|
59
63
|
|
|
60
|
-
R.add(1)('foo') // => will trigger warning in VSCode
|
|
64
|
+
R.add(1)('foo') // => will trigger warning in VSCode as it should
|
|
61
65
|
Ramda.add(1)('foo') // => will not trigger warning in VSCode
|
|
62
66
|
```
|
|
63
67
|
|
|
@@ -86,9 +90,7 @@ R.pick('a,b', {a: 1 , b: 2, c: 3} })
|
|
|
86
90
|
|
|
87
91
|
### Support
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
Closing the issue is usually accompanied by publishing a new patch version of `Rambda` to NPM.
|
|
93
|
+
One of the main issues with `Ramda` is the slow process of releasing new versions. This is not the case with **Rambda** as releases are made on regular basis.
|
|
92
94
|
|
|
93
95
|
[](#-rambdas-advantages)
|
|
94
96
|
|
|
@@ -96,13 +98,9 @@ Closing the issue is usually accompanied by publishing a new patch version of `R
|
|
|
96
98
|
|
|
97
99
|
<details>
|
|
98
100
|
<summary>
|
|
99
|
-
Click to see the full list of
|
|
101
|
+
Click to see the full list of 0 Ramda methods not implemented in Rambda and their status.
|
|
100
102
|
</summary>
|
|
101
103
|
|
|
102
|
-
- __
|
|
103
|
-
- construct
|
|
104
|
-
- constructN
|
|
105
|
-
- dissocPath
|
|
106
104
|
- dropRepeatsBy
|
|
107
105
|
- empty
|
|
108
106
|
- eqBy
|
|
@@ -154,8 +152,6 @@ Closing the issue is usually accompanied by publishing a new patch version of `R
|
|
|
154
152
|
- symmetricDifferenceWith
|
|
155
153
|
- andThen
|
|
156
154
|
- toPairsIn
|
|
157
|
-
- transduce
|
|
158
|
-
- traverse
|
|
159
155
|
- unary
|
|
160
156
|
- uncurryN
|
|
161
157
|
- unfold
|
|
@@ -167,6 +163,12 @@ Closing the issue is usually accompanied by publishing a new patch version of `R
|
|
|
167
163
|
- thunkify
|
|
168
164
|
- default
|
|
169
165
|
|
|
166
|
+
Most of above methods are in progress to be added to **Rambda**. The following methods are not going to be added:
|
|
167
|
+
- __ - placeholder method allows user to further customize the method call. While, it seems useful initially, the price is too high in terms of complexity for TypeScript definitions. If it is not easy exressable in TypeScript, it is not worth it as **Rambda** is a TypeScript first library.
|
|
168
|
+
- construct - Using classes is not very functional programming oriented.
|
|
169
|
+
- constructN - same as above
|
|
170
|
+
- transduce - currently is out of focus
|
|
171
|
+
- traverse - same as above
|
|
170
172
|
</details>
|
|
171
173
|
|
|
172
174
|
[](#-missing-ramda-methods)
|
|
@@ -184,7 +186,7 @@ https://unpkg.com/rambda@CURRENT_VERSION/dist/rambda.umd.js
|
|
|
184
186
|
- with deno
|
|
185
187
|
|
|
186
188
|
```
|
|
187
|
-
import {
|
|
189
|
+
import {add} from "https://deno.land/x/rambda/mod.ts";
|
|
188
190
|
```
|
|
189
191
|
|
|
190
192
|
[](#-install)
|
|
@@ -232,8 +234,8 @@ method | Rambda | Ramda | Lodash
|
|
|
232
234
|
--- |--- | --- | ---
|
|
233
235
|
*add* | 🚀 Fastest | 21.52% slower | 82.15% slower
|
|
234
236
|
*adjust* | 8.48% slower | 🚀 Fastest | 🔳
|
|
235
|
-
*all* | 🚀 Fastest |
|
|
236
|
-
*allPass* | 🚀 Fastest |
|
|
237
|
+
*all* | 🚀 Fastest | 7.18% slower | 🔳
|
|
238
|
+
*allPass* | 🚀 Fastest | 88.25% slower | 🔳
|
|
237
239
|
*allPass* | 🚀 Fastest | 98.56% slower | 🔳
|
|
238
240
|
*and* | 🚀 Fastest | 89.09% slower | 🔳
|
|
239
241
|
*any* | 🚀 Fastest | 92.87% slower | 45.82% slower
|
|
@@ -242,7 +244,7 @@ method | Rambda | Ramda | Lodash
|
|
|
242
244
|
*applySpec* | 🚀 Fastest | 80.43% slower | 🔳
|
|
243
245
|
*assoc* | 72.32% slower | 60.08% slower | 🚀 Fastest
|
|
244
246
|
*clone* | 🚀 Fastest | 91.86% slower | 86.48% slower
|
|
245
|
-
*compose* |
|
|
247
|
+
*compose* | 6.07% slower | 16.89% slower | 🚀 Fastest
|
|
246
248
|
*converge* | 78.63% slower | 🚀 Fastest | 🔳
|
|
247
249
|
*curry* | 🚀 Fastest | 28.86% slower | 🔳
|
|
248
250
|
*curryN* | 🚀 Fastest | 41.05% slower | 🔳
|
|
@@ -253,10 +255,10 @@ method | Rambda | Ramda | Lodash
|
|
|
253
255
|
*filter* | 6.7% slower | 72.03% slower | 🚀 Fastest
|
|
254
256
|
*find* | 🚀 Fastest | 85.14% slower | 42.65% slower
|
|
255
257
|
*findIndex* | 🚀 Fastest | 86.48% slower | 72.27% slower
|
|
256
|
-
*flatten* |
|
|
258
|
+
*flatten* | 🚀 Fastest | 85.68% slower | 3.57% slower
|
|
257
259
|
*ifElse* | 🚀 Fastest | 58.56% slower | 🔳
|
|
258
|
-
*includes* | 🚀 Fastest |
|
|
259
|
-
*indexOf* | 🚀 Fastest |
|
|
260
|
+
*includes* | 🚀 Fastest | 81.64% slower | 🔳
|
|
261
|
+
*indexOf* | 🚀 Fastest | 80.17% slower | 🔳
|
|
260
262
|
*indexOf* | 🚀 Fastest | 82.2% slower | 🔳
|
|
261
263
|
*init* | 🚀 Fastest | 92.24% slower | 13.3% slower
|
|
262
264
|
*is* | 🚀 Fastest | 57.69% slower | 🔳
|
|
@@ -272,7 +274,7 @@ method | Rambda | Ramda | Lodash
|
|
|
272
274
|
*over* | 🚀 Fastest | 56.23% slower | 🔳
|
|
273
275
|
*path* | 37.81% slower | 77.81% slower | 🚀 Fastest
|
|
274
276
|
*pick* | 🚀 Fastest | 19.07% slower | 80.2% slower
|
|
275
|
-
*pipe* | 0.
|
|
277
|
+
*pipe* | 🚀 Fastest | 0.11% slower | 🔳
|
|
276
278
|
*prop* | 🚀 Fastest | 87.95% slower | 🔳
|
|
277
279
|
*propEq* | 🚀 Fastest | 91.92% slower | 🔳
|
|
278
280
|
*range* | 🚀 Fastest | 61.8% slower | 57.44% slower
|
|
@@ -288,8 +290,9 @@ method | Rambda | Ramda | Lodash
|
|
|
288
290
|
*takeLast* | 🚀 Fastest | 93.39% slower | 19.22% slower
|
|
289
291
|
*test* | 🚀 Fastest | 82.34% slower | 🔳
|
|
290
292
|
*type* | 🚀 Fastest | 48.6% slower | 🔳
|
|
291
|
-
*uniq* | 🚀 Fastest |
|
|
292
|
-
*
|
|
293
|
+
*uniq* | 🚀 Fastest | 84.9% slower | 🔳
|
|
294
|
+
*uniqBy* | 51.93% slower | 🚀 Fastest | 🔳
|
|
295
|
+
*uniqWith* | 8.29% slower | 🚀 Fastest | 🔳
|
|
293
296
|
*uniqWith* | 14.23% slower | 🚀 Fastest | 🔳
|
|
294
297
|
*update* | 🚀 Fastest | 52.35% slower | 🔳
|
|
295
298
|
*view* | 🚀 Fastest | 76.15% slower | 🔳
|
|
@@ -925,6 +928,21 @@ describe('anyPass', () => {
|
|
|
925
928
|
const filtered2 = xs.filter(pred)
|
|
926
929
|
filtered2 // $ExpectType number[]
|
|
927
930
|
})
|
|
931
|
+
it('functions as a type guard', () => {
|
|
932
|
+
const isString = (x: unknown): x is string => typeof x === 'string'
|
|
933
|
+
const isNumber = (x: unknown): x is number => typeof x === 'number'
|
|
934
|
+
const isBoolean = (x: unknown): x is boolean => typeof x === 'boolean'
|
|
935
|
+
|
|
936
|
+
const isStringNumberOrBoolean = anyPass([isString, isNumber, isBoolean])
|
|
937
|
+
|
|
938
|
+
isStringNumberOrBoolean // $ExpectType (input: unknown) => boolean
|
|
939
|
+
|
|
940
|
+
const aValue: unknown = 1
|
|
941
|
+
|
|
942
|
+
if (isStringNumberOrBoolean(aValue)) {
|
|
943
|
+
aValue // $ExpectType unknown
|
|
944
|
+
}
|
|
945
|
+
})
|
|
928
946
|
})
|
|
929
947
|
```
|
|
930
948
|
|
|
@@ -1070,10 +1088,10 @@ test('happy', () => {
|
|
|
1070
1088
|
|
|
1071
1089
|
```typescript
|
|
1072
1090
|
|
|
1073
|
-
append<T>(
|
|
1091
|
+
append<T>(xToAppend: T, iterable: T[]): T[]
|
|
1074
1092
|
```
|
|
1075
1093
|
|
|
1076
|
-
It adds element `x` at the end of `
|
|
1094
|
+
It adds element `x` at the end of `iterable`.
|
|
1077
1095
|
|
|
1078
1096
|
<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>
|
|
1079
1097
|
|
|
@@ -1082,8 +1100,10 @@ It adds element `x` at the end of `list`.
|
|
|
1082
1100
|
<summary>All TypeScript definitions</summary>
|
|
1083
1101
|
|
|
1084
1102
|
```typescript
|
|
1085
|
-
append<T>(
|
|
1086
|
-
append<T>(
|
|
1103
|
+
append<T>(xToAppend: T, iterable: T[]): T[];
|
|
1104
|
+
append<T, U>(xToAppend: T, iterable: IsFirstSubtypeOfSecond<T, U>[]) : U[];
|
|
1105
|
+
append<T>(xToAppend: T): <U>(iterable: IsFirstSubtypeOfSecond<T, U>[]) => U[];
|
|
1106
|
+
append<T>(xToAppend: T): (iterable: T[]) => T[];
|
|
1087
1107
|
```
|
|
1088
1108
|
|
|
1089
1109
|
</details>
|
|
@@ -1114,7 +1134,8 @@ export function append(x, input){
|
|
|
1114
1134
|
<summary><strong>Tests</strong></summary>
|
|
1115
1135
|
|
|
1116
1136
|
```javascript
|
|
1117
|
-
import { append } from './append.js'
|
|
1137
|
+
// import { append } from './append.js'
|
|
1138
|
+
import { append } from 'ramda'
|
|
1118
1139
|
|
|
1119
1140
|
test('happy', () => {
|
|
1120
1141
|
expect(append('tests', [ 'write', 'more' ])).toEqual([
|
|
@@ -1140,20 +1161,62 @@ test('with strings', () => {
|
|
|
1140
1161
|
<summary><strong>TypeScript</strong> test</summary>
|
|
1141
1162
|
|
|
1142
1163
|
```typescript
|
|
1143
|
-
import {append} from 'rambda'
|
|
1164
|
+
import {append, prepend} from 'rambda'
|
|
1144
1165
|
|
|
1145
|
-
const
|
|
1166
|
+
const listOfNumbers = [1, 2, 3]
|
|
1167
|
+
const listOfNumbersAndStrings = [1, 'b', 3]
|
|
1146
1168
|
|
|
1147
|
-
describe('R.append', () => {
|
|
1148
|
-
|
|
1149
|
-
|
|
1169
|
+
describe('R.append/R.prepend', () => {
|
|
1170
|
+
describe("with the same primitive type as the array's elements", () => {
|
|
1171
|
+
it('uncurried', () => {
|
|
1172
|
+
// @ts-expect-error
|
|
1173
|
+
append('d', listOfNumbers)
|
|
1174
|
+
// @ts-expect-error
|
|
1175
|
+
prepend('d', listOfNumbers)
|
|
1176
|
+
append(4, listOfNumbers) // $ExpectType number[]
|
|
1177
|
+
prepend(4, listOfNumbers) // $ExpectType number[]
|
|
1178
|
+
})
|
|
1150
1179
|
|
|
1151
|
-
|
|
1180
|
+
it('curried', () => {
|
|
1181
|
+
// @ts-expect-error
|
|
1182
|
+
append('d')(listOfNumbers)
|
|
1183
|
+
append(4)(listOfNumbers) // $ExpectType number[]
|
|
1184
|
+
prepend(4)(listOfNumbers) // $ExpectType number[]
|
|
1185
|
+
})
|
|
1152
1186
|
})
|
|
1153
|
-
it('curried', () => {
|
|
1154
|
-
const result = append(4)(list)
|
|
1155
1187
|
|
|
1156
|
-
|
|
1188
|
+
describe("with a subtype of the array's elements", () => {
|
|
1189
|
+
it('uncurried', () => {
|
|
1190
|
+
// @ts-expect-error
|
|
1191
|
+
append(true, listOfNumbersAndStrings)
|
|
1192
|
+
append(4, listOfNumbersAndStrings) // $ExpectType (string | number)[]
|
|
1193
|
+
prepend(4, listOfNumbersAndStrings) // $ExpectType (string | number)[]
|
|
1194
|
+
})
|
|
1195
|
+
|
|
1196
|
+
it('curried', () => {
|
|
1197
|
+
// @ts-expect-error
|
|
1198
|
+
append(true)(listOfNumbersAndStrings)
|
|
1199
|
+
append(4)(listOfNumbersAndStrings) // $ExpectType (string | number)[]
|
|
1200
|
+
prepend(4)(listOfNumbersAndStrings) // $ExpectType (string | number)[]
|
|
1201
|
+
})
|
|
1202
|
+
})
|
|
1203
|
+
|
|
1204
|
+
describe("expanding the type of the array's elements", () => {
|
|
1205
|
+
it('uncurried', () => {
|
|
1206
|
+
// @ts-expect-error
|
|
1207
|
+
append('d', listOfNumbers)
|
|
1208
|
+
append<string | number>('d', listOfNumbers) // $ExpectType (string | number)[]
|
|
1209
|
+
prepend<string | number>('d', listOfNumbers) // $ExpectType (string | number)[]
|
|
1210
|
+
})
|
|
1211
|
+
|
|
1212
|
+
it('curried', () => {
|
|
1213
|
+
// @ts-expect-error
|
|
1214
|
+
append('d')(listOfNumbers)
|
|
1215
|
+
const appendD = append('d')
|
|
1216
|
+
appendD<string | number>(listOfNumbers) // $ExpectType (string | number)[]
|
|
1217
|
+
const prependD = prepend('d')
|
|
1218
|
+
prependD<string | number>(listOfNumbers) // $ExpectType (string | number)[]
|
|
1219
|
+
})
|
|
1157
1220
|
})
|
|
1158
1221
|
})
|
|
1159
1222
|
```
|
|
@@ -1745,21 +1808,17 @@ assocPath<Output>(path: Path): (newValue: any) => (obj: object) => Output;
|
|
|
1745
1808
|
|
|
1746
1809
|
```javascript
|
|
1747
1810
|
import { cloneList } from './_internals/cloneList.js'
|
|
1811
|
+
import { createPath } from './_internals/createPath.js'
|
|
1748
1812
|
import { isArray } from './_internals/isArray.js'
|
|
1749
|
-
import {
|
|
1750
|
-
import {
|
|
1813
|
+
import { isIndexInteger } from './_internals/isInteger.js'
|
|
1814
|
+
import { assocFn } from './assoc.js'
|
|
1751
1815
|
import { curry } from './curry.js'
|
|
1752
1816
|
|
|
1753
|
-
function assocPathFn(
|
|
1817
|
+
export function assocPathFn(
|
|
1754
1818
|
path, newValue, input
|
|
1755
1819
|
){
|
|
1756
|
-
const pathArrValue =
|
|
1757
|
-
|
|
1758
|
-
path.split('.').map(x => isInteger(Number(x)) ? Number(x) : x) :
|
|
1759
|
-
path
|
|
1760
|
-
if (pathArrValue.length === 0){
|
|
1761
|
-
return newValue
|
|
1762
|
-
}
|
|
1820
|
+
const pathArrValue = createPath(path)
|
|
1821
|
+
if (pathArrValue.length === 0) return newValue
|
|
1763
1822
|
|
|
1764
1823
|
const index = pathArrValue[ 0 ]
|
|
1765
1824
|
if (pathArrValue.length > 1){
|
|
@@ -1769,7 +1828,7 @@ function assocPathFn(
|
|
|
1769
1828
|
!input.hasOwnProperty(index)
|
|
1770
1829
|
|
|
1771
1830
|
const nextInput = condition ?
|
|
1772
|
-
|
|
1831
|
+
isIndexInteger(pathArrValue[ 1 ]) ?
|
|
1773
1832
|
[] :
|
|
1774
1833
|
{} :
|
|
1775
1834
|
input[ index ]
|
|
@@ -1781,14 +1840,14 @@ function assocPathFn(
|
|
|
1781
1840
|
)
|
|
1782
1841
|
}
|
|
1783
1842
|
|
|
1784
|
-
if (
|
|
1843
|
+
if (isIndexInteger(index) && isArray(input)){
|
|
1785
1844
|
const arr = cloneList(input)
|
|
1786
1845
|
arr[ index ] = newValue
|
|
1787
1846
|
|
|
1788
1847
|
return arr
|
|
1789
1848
|
}
|
|
1790
1849
|
|
|
1791
|
-
return
|
|
1850
|
+
return assocFn(
|
|
1792
1851
|
index, newValue, input
|
|
1793
1852
|
)
|
|
1794
1853
|
}
|
|
@@ -1803,21 +1862,45 @@ export const assocPath = curry(assocPathFn)
|
|
|
1803
1862
|
<summary><strong>Tests</strong></summary>
|
|
1804
1863
|
|
|
1805
1864
|
```javascript
|
|
1806
|
-
import {
|
|
1865
|
+
import { assocPathFn } from './assocPath.js'
|
|
1866
|
+
|
|
1867
|
+
test.only('happy', () => {
|
|
1868
|
+
const path = 'a.c.1'
|
|
1869
|
+
const input = {
|
|
1870
|
+
a : {
|
|
1871
|
+
b : 1,
|
|
1872
|
+
c : [ 1, 2 ],
|
|
1873
|
+
},
|
|
1874
|
+
}
|
|
1875
|
+
assocPathFn(
|
|
1876
|
+
path, 3, input
|
|
1877
|
+
)
|
|
1878
|
+
expect(input).toEqual({
|
|
1879
|
+
a : {
|
|
1880
|
+
b : 1,
|
|
1881
|
+
c : [ 1, 2 ],
|
|
1882
|
+
},
|
|
1883
|
+
})
|
|
1884
|
+
})
|
|
1807
1885
|
|
|
1808
1886
|
test('string can be used as path input', () => {
|
|
1809
1887
|
const testObj = {
|
|
1810
1888
|
a : [ { b : 1 }, { b : 2 } ],
|
|
1811
1889
|
d : 3,
|
|
1812
1890
|
}
|
|
1813
|
-
const
|
|
1891
|
+
const result1 = assocPathFn(
|
|
1892
|
+
[ 'a', 0, 'b' ], 10, testObj
|
|
1893
|
+
)
|
|
1894
|
+
const result2 = assocPathFn(
|
|
1814
1895
|
'a.0.b', 10, testObj
|
|
1815
1896
|
)
|
|
1897
|
+
|
|
1816
1898
|
const expected = {
|
|
1817
1899
|
a : [ { b : 10 }, { b : 2 } ],
|
|
1818
1900
|
d : 3,
|
|
1819
1901
|
}
|
|
1820
|
-
expect(
|
|
1902
|
+
expect(result1).toEqual(expected)
|
|
1903
|
+
expect(result2).toEqual(expected)
|
|
1821
1904
|
})
|
|
1822
1905
|
|
|
1823
1906
|
test('difference with ramda - doesn\'t overwrite primitive values with keys in the path', () => {
|
|
@@ -2987,6 +3070,10 @@ It returns a new object that does not contain property `prop`.
|
|
|
2987
3070
|
|
|
2988
3071
|
[](#dissoc)
|
|
2989
3072
|
|
|
3073
|
+
### dissocPath
|
|
3074
|
+
|
|
3075
|
+
[](#dissocPath)
|
|
3076
|
+
|
|
2990
3077
|
### divide
|
|
2991
3078
|
|
|
2992
3079
|
<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>
|
|
@@ -3350,6 +3437,10 @@ describe('R.dropRepeats', () => {
|
|
|
3350
3437
|
|
|
3351
3438
|
[](#dropRepeats)
|
|
3352
3439
|
|
|
3440
|
+
### dropRepeatsBy
|
|
3441
|
+
|
|
3442
|
+
[](#dropRepeatsBy)
|
|
3443
|
+
|
|
3353
3444
|
### dropRepeatsWith
|
|
3354
3445
|
|
|
3355
3446
|
<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')%2C%20list)%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>
|
|
@@ -3515,6 +3606,10 @@ describe('R.either', () => {
|
|
|
3515
3606
|
|
|
3516
3607
|
[](#either)
|
|
3517
3608
|
|
|
3609
|
+
### empty
|
|
3610
|
+
|
|
3611
|
+
[](#empty)
|
|
3612
|
+
|
|
3518
3613
|
### endsWith
|
|
3519
3614
|
|
|
3520
3615
|
```typescript
|
|
@@ -3676,6 +3771,10 @@ describe('R.endsWith - string', () => {
|
|
|
3676
3771
|
|
|
3677
3772
|
[](#endsWith)
|
|
3678
3773
|
|
|
3774
|
+
### eqBy
|
|
3775
|
+
|
|
3776
|
+
[](#eqBy)
|
|
3777
|
+
|
|
3679
3778
|
### eqProps
|
|
3680
3779
|
|
|
3681
3780
|
It returns `true` if property `prop` in `obj1` is equal to property `prop` in `obj2` according to `R.equals`.
|
|
@@ -3715,43 +3814,39 @@ import { isArray } from './_internals/isArray.js'
|
|
|
3715
3814
|
import { type } from './type.js'
|
|
3716
3815
|
|
|
3717
3816
|
export function _lastIndexOf(valueToFind, list){
|
|
3718
|
-
if (!isArray(list))
|
|
3817
|
+
if (!isArray(list))
|
|
3719
3818
|
throw new Error(`Cannot read property 'indexOf' of ${ list }`)
|
|
3720
|
-
|
|
3819
|
+
|
|
3721
3820
|
const typeOfValue = type(valueToFind)
|
|
3722
|
-
if (![ '
|
|
3821
|
+
if (![ 'Array', 'NaN', 'Object', 'RegExp' ].includes(typeOfValue))
|
|
3723
3822
|
return list.lastIndexOf(valueToFind)
|
|
3724
3823
|
|
|
3725
3824
|
const { length } = list
|
|
3726
3825
|
let index = length
|
|
3727
3826
|
let foundIndex = -1
|
|
3728
3827
|
|
|
3729
|
-
while (--index > -1 && foundIndex === -1)
|
|
3730
|
-
if (equals(list[ index ], valueToFind))
|
|
3828
|
+
while (--index > -1 && foundIndex === -1)
|
|
3829
|
+
if (equals(list[ index ], valueToFind))
|
|
3731
3830
|
foundIndex = index
|
|
3732
|
-
}
|
|
3733
|
-
}
|
|
3734
3831
|
|
|
3735
3832
|
return foundIndex
|
|
3736
3833
|
}
|
|
3737
3834
|
|
|
3738
3835
|
export function _indexOf(valueToFind, list){
|
|
3739
|
-
if (!isArray(list))
|
|
3836
|
+
if (!isArray(list))
|
|
3740
3837
|
throw new Error(`Cannot read property 'indexOf' of ${ list }`)
|
|
3741
|
-
|
|
3838
|
+
|
|
3742
3839
|
const typeOfValue = type(valueToFind)
|
|
3743
|
-
if (![ '
|
|
3840
|
+
if (![ 'Array', 'NaN', 'Object', 'RegExp' ].includes(typeOfValue))
|
|
3744
3841
|
return list.indexOf(valueToFind)
|
|
3745
3842
|
|
|
3746
3843
|
let index = -1
|
|
3747
3844
|
let foundIndex = -1
|
|
3748
3845
|
const { length } = list
|
|
3749
3846
|
|
|
3750
|
-
while (++index < length && foundIndex === -1)
|
|
3751
|
-
if (equals(list[ index ], valueToFind))
|
|
3847
|
+
while (++index < length && foundIndex === -1)
|
|
3848
|
+
if (equals(list[ index ], valueToFind))
|
|
3752
3849
|
foundIndex = index
|
|
3753
|
-
}
|
|
3754
|
-
}
|
|
3755
3850
|
|
|
3756
3851
|
return foundIndex
|
|
3757
3852
|
}
|
|
@@ -3759,17 +3854,16 @@ export function _indexOf(valueToFind, list){
|
|
|
3759
3854
|
function _arrayFromIterator(iter){
|
|
3760
3855
|
const list = []
|
|
3761
3856
|
let next
|
|
3762
|
-
while (!(next = iter.next()).done)
|
|
3857
|
+
while (!(next = iter.next()).done)
|
|
3763
3858
|
list.push(next.value)
|
|
3764
|
-
}
|
|
3765
3859
|
|
|
3766
3860
|
return list
|
|
3767
3861
|
}
|
|
3768
3862
|
|
|
3769
|
-
function
|
|
3770
|
-
if (a.size !== b.size)
|
|
3863
|
+
function _compareSets(a, b){
|
|
3864
|
+
if (a.size !== b.size)
|
|
3771
3865
|
return false
|
|
3772
|
-
|
|
3866
|
+
|
|
3773
3867
|
const aList = _arrayFromIterator(a.values())
|
|
3774
3868
|
const bList = _arrayFromIterator(b.values())
|
|
3775
3869
|
|
|
@@ -3778,11 +3872,11 @@ function _equalsSets(a, b){
|
|
|
3778
3872
|
return filtered.length === 0
|
|
3779
3873
|
}
|
|
3780
3874
|
|
|
3781
|
-
function
|
|
3782
|
-
|
|
3783
|
-
if (
|
|
3875
|
+
function compareErrors(a, b){
|
|
3876
|
+
if (a.message !== b.message) return false
|
|
3877
|
+
if (a.toString !== b.toString) return false
|
|
3784
3878
|
|
|
3785
|
-
return
|
|
3879
|
+
return a.toString() === b.toString()
|
|
3786
3880
|
}
|
|
3787
3881
|
|
|
3788
3882
|
function parseDate(maybeDate){
|
|
@@ -3803,40 +3897,36 @@ export function equals(a, b){
|
|
|
3803
3897
|
const aType = type(a)
|
|
3804
3898
|
|
|
3805
3899
|
if (aType !== type(b)) return false
|
|
3806
|
-
if (aType === 'Function')
|
|
3900
|
+
if (aType === 'Function')
|
|
3807
3901
|
return a.name === undefined ? false : a.name === b.name
|
|
3808
|
-
}
|
|
3809
3902
|
|
|
3810
|
-
if ([ 'NaN', '
|
|
3903
|
+
if ([ 'NaN', 'Null', 'Undefined' ].includes(aType)) return true
|
|
3811
3904
|
|
|
3812
|
-
if (
|
|
3905
|
+
if ([ 'BigInt', 'Number' ].includes(aType)){
|
|
3813
3906
|
if (Object.is(-0, a) !== Object.is(-0, b)) return false
|
|
3814
3907
|
|
|
3815
3908
|
return a.toString() === b.toString()
|
|
3816
3909
|
}
|
|
3817
3910
|
|
|
3818
|
-
if ([ '
|
|
3911
|
+
if ([ 'Boolean', 'String' ].includes(aType))
|
|
3819
3912
|
return a.toString() === b.toString()
|
|
3820
|
-
}
|
|
3821
3913
|
|
|
3822
3914
|
if (aType === 'Array'){
|
|
3823
3915
|
const aClone = Array.from(a)
|
|
3824
3916
|
const bClone = Array.from(b)
|
|
3825
3917
|
|
|
3826
|
-
if (aClone.toString() !== bClone.toString())
|
|
3918
|
+
if (aClone.toString() !== bClone.toString())
|
|
3827
3919
|
return false
|
|
3828
|
-
}
|
|
3829
3920
|
|
|
3830
3921
|
let loopArrayFlag = true
|
|
3831
3922
|
aClone.forEach((aCloneInstance, aCloneIndex) => {
|
|
3832
|
-
if (loopArrayFlag)
|
|
3923
|
+
if (loopArrayFlag)
|
|
3833
3924
|
if (
|
|
3834
3925
|
aCloneInstance !== bClone[ aCloneIndex ] &&
|
|
3835
3926
|
!equals(aCloneInstance, bClone[ aCloneIndex ])
|
|
3836
|
-
)
|
|
3927
|
+
)
|
|
3837
3928
|
loopArrayFlag = false
|
|
3838
|
-
|
|
3839
|
-
}
|
|
3929
|
+
|
|
3840
3930
|
})
|
|
3841
3931
|
|
|
3842
3932
|
return loopArrayFlag
|
|
@@ -3845,34 +3935,31 @@ export function equals(a, b){
|
|
|
3845
3935
|
const aRegex = parseRegex(a)
|
|
3846
3936
|
const bRegex = parseRegex(b)
|
|
3847
3937
|
|
|
3848
|
-
if (aRegex[ 0 ])
|
|
3938
|
+
if (aRegex[ 0 ])
|
|
3849
3939
|
return bRegex[ 0 ] ? aRegex[ 1 ] === bRegex[ 1 ] : false
|
|
3850
|
-
|
|
3940
|
+
else if (bRegex[ 0 ]) return false
|
|
3851
3941
|
|
|
3852
3942
|
const aDate = parseDate(a)
|
|
3853
3943
|
const bDate = parseDate(b)
|
|
3854
3944
|
|
|
3855
|
-
if (aDate[ 0 ])
|
|
3945
|
+
if (aDate[ 0 ])
|
|
3856
3946
|
return bDate[ 0 ] ? aDate[ 1 ] === bDate[ 1 ] : false
|
|
3857
|
-
|
|
3947
|
+
else if (bDate[ 0 ]) return false
|
|
3858
3948
|
|
|
3859
|
-
|
|
3860
|
-
|
|
3949
|
+
if (a instanceof Error){
|
|
3950
|
+
if (!(b instanceof Error)) return false
|
|
3861
3951
|
|
|
3862
|
-
|
|
3863
|
-
return bError[ 0 ] ?
|
|
3864
|
-
aError[ 0 ] === bError[ 0 ] && aError[ 1 ] === bError[ 1 ] :
|
|
3865
|
-
false
|
|
3866
|
-
}
|
|
3867
|
-
if (aType === 'Set'){
|
|
3868
|
-
return _equalsSets(a, b)
|
|
3952
|
+
return compareErrors(a, b)
|
|
3869
3953
|
}
|
|
3954
|
+
|
|
3955
|
+
if (aType === 'Set')
|
|
3956
|
+
return _compareSets(a, b)
|
|
3957
|
+
|
|
3870
3958
|
if (aType === 'Object'){
|
|
3871
3959
|
const aKeys = Object.keys(a)
|
|
3872
3960
|
|
|
3873
|
-
if (aKeys.length !== Object.keys(b).length)
|
|
3961
|
+
if (aKeys.length !== Object.keys(b).length)
|
|
3874
3962
|
return false
|
|
3875
|
-
}
|
|
3876
3963
|
|
|
3877
3964
|
let loopObjectFlag = true
|
|
3878
3965
|
aKeys.forEach(aKeyInstance => {
|
|
@@ -3880,9 +3967,9 @@ export function equals(a, b){
|
|
|
3880
3967
|
const aValue = a[ aKeyInstance ]
|
|
3881
3968
|
const bValue = b[ aKeyInstance ]
|
|
3882
3969
|
|
|
3883
|
-
if (aValue !== bValue && !equals(aValue, bValue))
|
|
3970
|
+
if (aValue !== bValue && !equals(aValue, bValue))
|
|
3884
3971
|
loopObjectFlag = false
|
|
3885
|
-
|
|
3972
|
+
|
|
3886
3973
|
}
|
|
3887
3974
|
})
|
|
3888
3975
|
|
|
@@ -3969,6 +4056,7 @@ test('new Error', () => {
|
|
|
3969
4056
|
expect(equals(new Error('XXX'), new Error('YYY'))).toBeFalse()
|
|
3970
4057
|
expect(equals(new Error('XXX'), new Error('XXX'))).toBeTrue()
|
|
3971
4058
|
expect(equals(new Error('XXX'), new TypeError('YYY'))).toBeFalse()
|
|
4059
|
+
expect(equals(new Error('XXX'), new Error('XXX'))).toBeTrue()
|
|
3972
4060
|
})
|
|
3973
4061
|
|
|
3974
4062
|
test('with dates', () => {
|
|
@@ -3997,8 +4085,8 @@ test('ramda spec', () => {
|
|
|
3997
4085
|
b : 3,
|
|
3998
4086
|
},
|
|
3999
4087
|
{
|
|
4000
|
-
b : 3,
|
|
4001
4088
|
a : 2,
|
|
4089
|
+
b : 3,
|
|
4002
4090
|
})).toBeTrue()
|
|
4003
4091
|
|
|
4004
4092
|
expect(equals({
|
|
@@ -4094,8 +4182,8 @@ test('various examples', () => {
|
|
|
4094
4182
|
b : 2,
|
|
4095
4183
|
},
|
|
4096
4184
|
{
|
|
4097
|
-
b : 2,
|
|
4098
4185
|
a : 1,
|
|
4186
|
+
b : 2,
|
|
4099
4187
|
})).toBeTrue()
|
|
4100
4188
|
|
|
4101
4189
|
expect(equals({
|
|
@@ -4121,8 +4209,8 @@ test('various examples', () => {
|
|
|
4121
4209
|
b : 2,
|
|
4122
4210
|
},
|
|
4123
4211
|
{
|
|
4124
|
-
b : 2,
|
|
4125
4212
|
a : 1,
|
|
4213
|
+
b : 2,
|
|
4126
4214
|
c : 3,
|
|
4127
4215
|
})).toBeFalse()
|
|
4128
4216
|
|
|
@@ -4134,8 +4222,8 @@ test('various examples', () => {
|
|
|
4134
4222
|
},
|
|
4135
4223
|
{
|
|
4136
4224
|
x : {
|
|
4137
|
-
b : 2,
|
|
4138
4225
|
a : 1,
|
|
4226
|
+
b : 2,
|
|
4139
4227
|
c : 3,
|
|
4140
4228
|
},
|
|
4141
4229
|
})).toBeFalse()
|
|
@@ -4145,8 +4233,8 @@ test('various examples', () => {
|
|
|
4145
4233
|
b : 2,
|
|
4146
4234
|
},
|
|
4147
4235
|
{
|
|
4148
|
-
b : 3,
|
|
4149
4236
|
a : 1,
|
|
4237
|
+
b : 3,
|
|
4150
4238
|
})).toBeFalse()
|
|
4151
4239
|
|
|
4152
4240
|
expect(equals({ a : { b : { c : 1 } } }, { a : { b : { c : 1 } } })).toBeTrue()
|
|
@@ -4195,26 +4283,32 @@ test('with negative zero', () => {
|
|
|
4195
4283
|
expect(equals(-0, 1)).toBeFalse()
|
|
4196
4284
|
})
|
|
4197
4285
|
|
|
4198
|
-
|
|
4286
|
+
test('with big int', () => {
|
|
4287
|
+
const a = BigInt(9007199254740991)
|
|
4288
|
+
const b = BigInt(9007199254740991)
|
|
4289
|
+
const c = BigInt(7007199254740991)
|
|
4290
|
+
expect(equals(a, b)).toBeTrue()
|
|
4291
|
+
expect(equals(a, c)).toBeFalse()
|
|
4292
|
+
})
|
|
4199
4293
|
|
|
4200
4294
|
describe('brute force', () => {
|
|
4201
4295
|
compareCombinations({
|
|
4202
|
-
|
|
4203
|
-
fnRamda : equalsRamda,
|
|
4204
|
-
firstInput : possibleInputs,
|
|
4205
|
-
secondInput : possibleInputs,
|
|
4206
|
-
callback : errorsCounters => {
|
|
4296
|
+
callback : errorsCounters => {
|
|
4207
4297
|
expect(errorsCounters).toMatchInlineSnapshot(`
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4298
|
+
{
|
|
4299
|
+
"ERRORS_MESSAGE_MISMATCH": 0,
|
|
4300
|
+
"ERRORS_TYPE_MISMATCH": 0,
|
|
4301
|
+
"RESULTS_MISMATCH": 8,
|
|
4302
|
+
"SHOULD_NOT_THROW": 0,
|
|
4303
|
+
"SHOULD_THROW": 0,
|
|
4304
|
+
"TOTAL_TESTS": 289,
|
|
4305
|
+
}
|
|
4306
|
+
`)
|
|
4217
4307
|
},
|
|
4308
|
+
firstInput : variousTypes,
|
|
4309
|
+
fn : equals,
|
|
4310
|
+
fnRamda : equalsRamda,
|
|
4311
|
+
secondInput : variousTypes,
|
|
4218
4312
|
})
|
|
4219
4313
|
})
|
|
4220
4314
|
```
|
|
@@ -5339,36 +5433,46 @@ forEach<T, U>(fn: ObjectIterator<T, void>): (list: Dictionary<T>) => Dictionary<
|
|
|
5339
5433
|
import { isArray } from './_internals/isArray.js'
|
|
5340
5434
|
import { keys } from './_internals/keys.js'
|
|
5341
5435
|
|
|
5342
|
-
export function
|
|
5343
|
-
|
|
5436
|
+
export function forEachObjIndexedFn(fn, obj){
|
|
5437
|
+
let index = 0
|
|
5438
|
+
const listKeys = keys(obj)
|
|
5439
|
+
const len = listKeys.length
|
|
5344
5440
|
|
|
5345
|
-
|
|
5346
|
-
|
|
5441
|
+
while (index < len){
|
|
5442
|
+
const key = listKeys[ index ]
|
|
5443
|
+
fn(
|
|
5444
|
+
obj[ key ], key, obj
|
|
5445
|
+
)
|
|
5446
|
+
index++
|
|
5347
5447
|
}
|
|
5348
5448
|
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
const len = list.length
|
|
5449
|
+
return obj
|
|
5450
|
+
}
|
|
5352
5451
|
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5452
|
+
export function forEachObjIndexed(fn, list){
|
|
5453
|
+
if (arguments.length === 1) return _list => forEachObjIndexed(fn, _list)
|
|
5454
|
+
|
|
5455
|
+
if (list === undefined) return
|
|
5456
|
+
|
|
5457
|
+
return forEachObjIndexedFn(fn, list)
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5460
|
+
export function forEach(fn, iterable){
|
|
5461
|
+
if (arguments.length === 1) return _list => forEach(fn, _list)
|
|
5462
|
+
|
|
5463
|
+
if (iterable === undefined) return
|
|
5464
|
+
|
|
5465
|
+
if (isArray(iterable)){
|
|
5358
5466
|
let index = 0
|
|
5359
|
-
const
|
|
5360
|
-
const len = listKeys.length
|
|
5467
|
+
const len = iterable.length
|
|
5361
5468
|
|
|
5362
5469
|
while (index < len){
|
|
5363
|
-
|
|
5364
|
-
fn(
|
|
5365
|
-
list[ key ], key, list
|
|
5366
|
-
)
|
|
5470
|
+
fn(iterable[ index ])
|
|
5367
5471
|
index++
|
|
5368
5472
|
}
|
|
5369
|
-
}
|
|
5473
|
+
} else return forEachObjIndexedFn(fn, iterable)
|
|
5370
5474
|
|
|
5371
|
-
return
|
|
5475
|
+
return iterable
|
|
5372
5476
|
}
|
|
5373
5477
|
```
|
|
5374
5478
|
|
|
@@ -5499,6 +5603,10 @@ describe('R.forEach with objects', () => {
|
|
|
5499
5603
|
|
|
5500
5604
|
[](#forEach)
|
|
5501
5605
|
|
|
5606
|
+
### forEachObjIndexed
|
|
5607
|
+
|
|
5608
|
+
[](#forEachObjIndexed)
|
|
5609
|
+
|
|
5502
5610
|
### fromPairs
|
|
5503
5611
|
|
|
5504
5612
|
It transforms a `listOfPairs` to an object.
|
|
@@ -5716,7 +5824,7 @@ describe('R.hasPath', () => {
|
|
|
5716
5824
|
|
|
5717
5825
|
```typescript
|
|
5718
5826
|
|
|
5719
|
-
head(
|
|
5827
|
+
head(str: string): string
|
|
5720
5828
|
```
|
|
5721
5829
|
|
|
5722
5830
|
It returns the first element of list or string `input`.
|
|
@@ -5728,8 +5836,10 @@ It returns the first element of list or string `input`.
|
|
|
5728
5836
|
<summary>All TypeScript definitions</summary>
|
|
5729
5837
|
|
|
5730
5838
|
```typescript
|
|
5731
|
-
head(
|
|
5732
|
-
head(
|
|
5839
|
+
head(str: string): string;
|
|
5840
|
+
head(str: ''): undefined;
|
|
5841
|
+
head<T>(list: never[]): undefined;
|
|
5842
|
+
head<T extends unknown[]>(array: T): FirstArrayElement<T>
|
|
5733
5843
|
head<T extends readonly unknown[]>(array: T): FirstArrayElement<T>
|
|
5734
5844
|
```
|
|
5735
5845
|
|
|
@@ -5771,34 +5881,46 @@ test('head', () => {
|
|
|
5771
5881
|
<summary><strong>TypeScript</strong> test</summary>
|
|
5772
5882
|
|
|
5773
5883
|
```typescript
|
|
5774
|
-
import {
|
|
5775
|
-
|
|
5884
|
+
import {
|
|
5885
|
+
emptyList,
|
|
5886
|
+
emptyString,
|
|
5887
|
+
mixedList,
|
|
5888
|
+
mixedListConst,
|
|
5889
|
+
numberList,
|
|
5890
|
+
numberListConst,
|
|
5891
|
+
string,
|
|
5892
|
+
} from '_internals/typescriptTestUtils'
|
|
5893
|
+
import {head, last} from 'rambda'
|
|
5776
5894
|
|
|
5777
5895
|
describe('R.head', () => {
|
|
5778
5896
|
it('string', () => {
|
|
5779
|
-
|
|
5780
|
-
|
|
5897
|
+
head(string) // $ExpectType string
|
|
5898
|
+
last(string) // $ExpectType string
|
|
5781
5899
|
})
|
|
5782
|
-
it('
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
})
|
|
5786
|
-
it('mixed', () => {
|
|
5787
|
-
const result = head(mixedList)
|
|
5788
|
-
result // $ExpectType string | number
|
|
5900
|
+
it('empty string', () => {
|
|
5901
|
+
head(emptyString) // $ExpectType undefined
|
|
5902
|
+
last(emptyString) // $ExpectType undefined
|
|
5789
5903
|
})
|
|
5790
|
-
it('
|
|
5791
|
-
|
|
5792
|
-
|
|
5904
|
+
it('array', () => {
|
|
5905
|
+
head(numberList) // $ExpectType number
|
|
5906
|
+
head(numberListConst) // $ExpectType 1
|
|
5907
|
+
|
|
5908
|
+
last(numberList) // $ExpectType number
|
|
5909
|
+
last(numberListConst) // $ExpectType 3
|
|
5793
5910
|
})
|
|
5794
|
-
it('empty array
|
|
5795
|
-
const
|
|
5796
|
-
|
|
5911
|
+
it('empty array', () => {
|
|
5912
|
+
const list = [] as const
|
|
5913
|
+
head(emptyList) // $ExpectType undefined
|
|
5914
|
+
head(list) // $ExpectType never
|
|
5915
|
+
last(emptyList) // $ExpectType undefined
|
|
5916
|
+
last(list) // $ExpectType never
|
|
5797
5917
|
})
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5918
|
+
|
|
5919
|
+
it('mixed', () => {
|
|
5920
|
+
head(mixedList) // $ExpectType string | number
|
|
5921
|
+
head(mixedListConst) // $ExpectType 1
|
|
5922
|
+
last(mixedList) // $ExpectType string | number
|
|
5923
|
+
last(mixedListConst) // $ExpectType "bar"
|
|
5802
5924
|
})
|
|
5803
5925
|
})
|
|
5804
5926
|
```
|
|
@@ -6693,7 +6815,7 @@ describe('R.juxt', () => {
|
|
|
6693
6815
|
|
|
6694
6816
|
```typescript
|
|
6695
6817
|
|
|
6696
|
-
keys<T extends object>(x: T): (keyof T)[]
|
|
6818
|
+
keys<T extends object>(x: T): (keyof T & string)[]
|
|
6697
6819
|
```
|
|
6698
6820
|
|
|
6699
6821
|
It applies `Object.keys` over `x` and returns its keys.
|
|
@@ -6705,7 +6827,7 @@ It applies `Object.keys` over `x` and returns its keys.
|
|
|
6705
6827
|
<summary>All TypeScript definitions</summary>
|
|
6706
6828
|
|
|
6707
6829
|
```typescript
|
|
6708
|
-
keys<T extends object>(x: T): (keyof T)[];
|
|
6830
|
+
keys<T extends object>(x: T): (keyof T & string)[];
|
|
6709
6831
|
keys<T>(x: T): string[];
|
|
6710
6832
|
```
|
|
6711
6833
|
|
|
@@ -6737,32 +6859,13 @@ test('happy', () => {
|
|
|
6737
6859
|
|
|
6738
6860
|
</details>
|
|
6739
6861
|
|
|
6740
|
-
<details>
|
|
6741
|
-
|
|
6742
|
-
<summary><strong>TypeScript</strong> test</summary>
|
|
6743
|
-
|
|
6744
|
-
```typescript
|
|
6745
|
-
import {keys} from 'rambda'
|
|
6746
|
-
|
|
6747
|
-
const obj = {a: 1, b: 2}
|
|
6748
|
-
|
|
6749
|
-
describe('R.keys', () => {
|
|
6750
|
-
it('happy', () => {
|
|
6751
|
-
const result = keys(obj)
|
|
6752
|
-
result // $ExpectType ("b" | "a")[]
|
|
6753
|
-
})
|
|
6754
|
-
})
|
|
6755
|
-
```
|
|
6756
|
-
|
|
6757
|
-
</details>
|
|
6758
|
-
|
|
6759
6862
|
[](#keys)
|
|
6760
6863
|
|
|
6761
6864
|
### last
|
|
6762
6865
|
|
|
6763
6866
|
```typescript
|
|
6764
6867
|
|
|
6765
|
-
last(
|
|
6868
|
+
last(str: ''): undefined
|
|
6766
6869
|
```
|
|
6767
6870
|
|
|
6768
6871
|
It returns the last element of `input`, as the `input` can be either a string or an array.
|
|
@@ -6774,8 +6877,10 @@ It returns the last element of `input`, as the `input` can be either a string or
|
|
|
6774
6877
|
<summary>All TypeScript definitions</summary>
|
|
6775
6878
|
|
|
6776
6879
|
```typescript
|
|
6777
|
-
last(
|
|
6778
|
-
last(
|
|
6880
|
+
last(str: ''): undefined;
|
|
6881
|
+
last(str: string): string;
|
|
6882
|
+
last(list: never[]): undefined;
|
|
6883
|
+
last<T extends unknown[]>(array: T): LastArrayElement<T>
|
|
6779
6884
|
last<T extends readonly unknown[]>(array: T): LastArrayElement<T>
|
|
6780
6885
|
```
|
|
6781
6886
|
|
|
@@ -6817,45 +6922,6 @@ test('with string', () => {
|
|
|
6817
6922
|
|
|
6818
6923
|
</details>
|
|
6819
6924
|
|
|
6820
|
-
<details>
|
|
6821
|
-
|
|
6822
|
-
<summary><strong>TypeScript</strong> test</summary>
|
|
6823
|
-
|
|
6824
|
-
```typescript
|
|
6825
|
-
import {mixedList, mixedListConst} from '_internals/typescriptTestUtils'
|
|
6826
|
-
import {last} from 'rambda'
|
|
6827
|
-
|
|
6828
|
-
describe('R.last', () => {
|
|
6829
|
-
it('string', () => {
|
|
6830
|
-
const result = last('foo')
|
|
6831
|
-
result // $ExpectType string
|
|
6832
|
-
})
|
|
6833
|
-
it('array', () => {
|
|
6834
|
-
const result = last([1, 2, 3])
|
|
6835
|
-
result // $ExpectType number
|
|
6836
|
-
})
|
|
6837
|
-
it('mixed', () => {
|
|
6838
|
-
const result = last(mixedList)
|
|
6839
|
-
result // $ExpectType string | number
|
|
6840
|
-
})
|
|
6841
|
-
it('mixed const', () => {
|
|
6842
|
-
const result = last(mixedListConst)
|
|
6843
|
-
result // $ExpectType "bar"
|
|
6844
|
-
})
|
|
6845
|
-
it('empty array - case 1', () => {
|
|
6846
|
-
const result = last([])
|
|
6847
|
-
result // $ExpectType undefined
|
|
6848
|
-
})
|
|
6849
|
-
it('empty array - case 2', () => {
|
|
6850
|
-
const list = ['foo', 'bar'].filter(x => x.startsWith('a'))
|
|
6851
|
-
const result = last(list)
|
|
6852
|
-
result // $ExpectType string
|
|
6853
|
-
})
|
|
6854
|
-
})
|
|
6855
|
-
```
|
|
6856
|
-
|
|
6857
|
-
</details>
|
|
6858
|
-
|
|
6859
6925
|
[](#last)
|
|
6860
6926
|
|
|
6861
6927
|
### lastIndexOf
|
|
@@ -8739,7 +8805,7 @@ mergeWith<Output>(fn: (x: any, z: any) => any): <U, V>(a: U, b: V) => Output;
|
|
|
8739
8805
|
```javascript
|
|
8740
8806
|
import { curry } from './curry.js'
|
|
8741
8807
|
|
|
8742
|
-
function mergeWithFn(
|
|
8808
|
+
export function mergeWithFn(
|
|
8743
8809
|
mergeFn, aInput, bInput
|
|
8744
8810
|
){
|
|
8745
8811
|
const a = aInput ?? {}
|
|
@@ -8747,21 +8813,15 @@ function mergeWithFn(
|
|
|
8747
8813
|
const willReturn = {}
|
|
8748
8814
|
|
|
8749
8815
|
Object.keys(a).forEach(key => {
|
|
8750
|
-
if (b[ key ] === undefined)
|
|
8751
|
-
|
|
8752
|
-
} else {
|
|
8753
|
-
willReturn[ key ] = mergeFn(a[ key ], b[ key ])
|
|
8754
|
-
}
|
|
8816
|
+
if (b[ key ] === undefined) willReturn[ key ] = a[ key ]
|
|
8817
|
+
else willReturn[ key ] = mergeFn(a[ key ], b[ key ])
|
|
8755
8818
|
})
|
|
8756
8819
|
|
|
8757
8820
|
Object.keys(b).forEach(key => {
|
|
8758
8821
|
if (willReturn[ key ] !== undefined) return
|
|
8759
8822
|
|
|
8760
|
-
if (a[ key ] === undefined)
|
|
8761
|
-
|
|
8762
|
-
} else {
|
|
8763
|
-
willReturn[ key ] = mergeFn(a[ key ], b[ key ])
|
|
8764
|
-
}
|
|
8823
|
+
if (a[ key ] === undefined) willReturn[ key ] = b[ key ]
|
|
8824
|
+
else willReturn[ key ] = mergeFn(a[ key ], b[ key ])
|
|
8765
8825
|
})
|
|
8766
8826
|
|
|
8767
8827
|
return willReturn
|
|
@@ -8778,10 +8838,10 @@ export const mergeWith = curry(mergeWithFn)
|
|
|
8778
8838
|
|
|
8779
8839
|
```javascript
|
|
8780
8840
|
import { concat } from './concat.js'
|
|
8781
|
-
import {
|
|
8841
|
+
import { mergeWithFn } from './mergeWith.js'
|
|
8782
8842
|
|
|
8783
8843
|
test('happy', () => {
|
|
8784
|
-
const result =
|
|
8844
|
+
const result = mergeWithFn(
|
|
8785
8845
|
concat,
|
|
8786
8846
|
{
|
|
8787
8847
|
a : true,
|
|
@@ -8794,8 +8854,8 @@ test('happy', () => {
|
|
|
8794
8854
|
)
|
|
8795
8855
|
const expected = {
|
|
8796
8856
|
a : true,
|
|
8797
|
-
values : [ 10, 20, 15, 35 ],
|
|
8798
8857
|
b : true,
|
|
8858
|
+
values : [ 10, 20, 15, 35 ],
|
|
8799
8859
|
}
|
|
8800
8860
|
expect(result).toEqual(expected)
|
|
8801
8861
|
})
|
|
@@ -8803,31 +8863,31 @@ test('happy', () => {
|
|
|
8803
8863
|
// https://github.com/ramda/ramda/pull/3222/files#diff-d925d9188b478d2f1d4b26012c6dddac374f9e9d7a336604d654b9a113bfc857
|
|
8804
8864
|
describe('acts as if nil values are simply empty objects', () => {
|
|
8805
8865
|
it('if the first object is nil and the second empty', () => {
|
|
8806
|
-
expect(
|
|
8866
|
+
expect(mergeWithFn(
|
|
8807
8867
|
concat, undefined, {}
|
|
8808
8868
|
)).toEqual({})
|
|
8809
8869
|
})
|
|
8810
8870
|
|
|
8811
8871
|
it('if the first object is empty and the second nil', () => {
|
|
8812
|
-
expect(
|
|
8872
|
+
expect(mergeWithFn(
|
|
8813
8873
|
concat, {}, null
|
|
8814
8874
|
)).toEqual({})
|
|
8815
8875
|
})
|
|
8816
8876
|
|
|
8817
8877
|
it('if both objects are nil', () => {
|
|
8818
|
-
expect(
|
|
8878
|
+
expect(mergeWithFn(
|
|
8819
8879
|
concat, undefined, null
|
|
8820
8880
|
)).toEqual({})
|
|
8821
8881
|
})
|
|
8822
8882
|
|
|
8823
8883
|
it('if the first object is not empty and the second is nil', () => {
|
|
8824
|
-
expect(
|
|
8884
|
+
expect(mergeWithFn(
|
|
8825
8885
|
concat, { a : 'a' }, null
|
|
8826
8886
|
)).toEqual({ a : 'a' })
|
|
8827
8887
|
})
|
|
8828
8888
|
|
|
8829
8889
|
it('if the first object is nil and the second is not empty', () => {
|
|
8830
|
-
expect(
|
|
8890
|
+
expect(mergeWithFn(
|
|
8831
8891
|
concat, undefined, { a : 'a' }
|
|
8832
8892
|
)).toEqual({ a : 'a' })
|
|
8833
8893
|
})
|
|
@@ -9634,22 +9694,20 @@ omit<T>(propsToOmit: string): (obj: object) => T;
|
|
|
9634
9694
|
|
|
9635
9695
|
```javascript
|
|
9636
9696
|
import { createPath } from './_internals/createPath.js'
|
|
9697
|
+
import { includes } from './_internals/includes.js'
|
|
9637
9698
|
|
|
9638
9699
|
export function omit(propsToOmit, obj){
|
|
9639
9700
|
if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)
|
|
9640
9701
|
|
|
9641
|
-
if (obj === null || obj === undefined)
|
|
9702
|
+
if (obj === null || obj === undefined)
|
|
9642
9703
|
return undefined
|
|
9643
|
-
}
|
|
9644
9704
|
|
|
9645
9705
|
const propsToOmitValue = createPath(propsToOmit, ',')
|
|
9646
9706
|
const willReturn = {}
|
|
9647
9707
|
|
|
9648
|
-
for (const key in obj)
|
|
9649
|
-
if (!
|
|
9708
|
+
for (const key in obj)
|
|
9709
|
+
if (!includes(key, propsToOmitValue))
|
|
9650
9710
|
willReturn[ key ] = obj[ key ]
|
|
9651
|
-
}
|
|
9652
|
-
}
|
|
9653
9711
|
|
|
9654
9712
|
return willReturn
|
|
9655
9713
|
}
|
|
@@ -9678,18 +9736,17 @@ test('with string as condition', () => {
|
|
|
9678
9736
|
expect(resultCurry).toEqual(expectedResult)
|
|
9679
9737
|
})
|
|
9680
9738
|
|
|
9681
|
-
test('with
|
|
9682
|
-
|
|
9739
|
+
test.only('with number as property to omit', () => {
|
|
9740
|
+
const obj = {
|
|
9741
|
+
1 : 1,
|
|
9742
|
+
b : 2,
|
|
9743
|
+
}
|
|
9744
|
+
const result = omit([ 1 ], obj)
|
|
9745
|
+
expect(result).toEqual({ b : 2 })
|
|
9683
9746
|
})
|
|
9684
9747
|
|
|
9685
|
-
test('
|
|
9686
|
-
expect(omit(
|
|
9687
|
-
a : 1,
|
|
9688
|
-
42 : 2,
|
|
9689
|
-
})).toEqual({
|
|
9690
|
-
42 : 2,
|
|
9691
|
-
a : 1,
|
|
9692
|
-
})
|
|
9748
|
+
test('with null', () => {
|
|
9749
|
+
expect(omit('a,b', null)).toBeUndefined()
|
|
9693
9750
|
})
|
|
9694
9751
|
|
|
9695
9752
|
test('happy', () => {
|
|
@@ -10053,10 +10110,19 @@ The name comes from the fact that you partially inject the inputs.
|
|
|
10053
10110
|
partial<V0, V1, T>(fn: (x0: V0, x1: V1) => T, args: [V0]): (x1: V1) => T;
|
|
10054
10111
|
partial<V0, V1, V2, T>(fn: (x0: V0, x1: V1, x2: V2) => T, args: [V0, V1]): (x2: V2) => T;
|
|
10055
10112
|
partial<V0, V1, V2, T>(fn: (x0: V0, x1: V1, x2: V2) => T, args: [V0]): (x1: V1, x2: V2) => T;
|
|
10056
|
-
partial<V0, V1, V2, V3, T>(
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10113
|
+
partial<V0, V1, V2, V3, T>(
|
|
10114
|
+
fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T,
|
|
10115
|
+
args: [V0, V1, V2],
|
|
10116
|
+
): (x2: V3) => T;
|
|
10117
|
+
partial<V0, V1, V2, V3, T>(
|
|
10118
|
+
fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T,
|
|
10119
|
+
args: [V0, V1],
|
|
10120
|
+
): (x2: V2, x3: V3) => T;
|
|
10121
|
+
partial<V0, V1, V2, V3, T>(
|
|
10122
|
+
fn: (x0: V0, x1: V1, x2: V2, x3: V3) => T,
|
|
10123
|
+
args: [V0],
|
|
10124
|
+
): (x1: V1, x2: V2, x3: V3) => T;
|
|
10125
|
+
partial<T>(fn: (...a: any[]) => T, args: any[]): (...a: any[]) => T;
|
|
10060
10126
|
```
|
|
10061
10127
|
|
|
10062
10128
|
</details>
|
|
@@ -10066,15 +10132,21 @@ partial<T>(fn: (...a: any[]) => T, args: any[]): (...x: any[]) => T;
|
|
|
10066
10132
|
<summary><strong>R.partial</strong> source</summary>
|
|
10067
10133
|
|
|
10068
10134
|
```javascript
|
|
10135
|
+
import { isArray } from './_internals/isArray.js'
|
|
10136
|
+
|
|
10069
10137
|
export function partial(fn, ...args){
|
|
10070
10138
|
const len = fn.length
|
|
10071
10139
|
|
|
10140
|
+
// If a single array argument is given, those are the args (a la Ramda).
|
|
10141
|
+
// Otherwise, the variadic arguments are the args.
|
|
10142
|
+
const argList = args.length === 1 && isArray(args[0]) ? args[0] : args
|
|
10143
|
+
|
|
10072
10144
|
return (...rest) => {
|
|
10073
|
-
if (
|
|
10074
|
-
return fn(...
|
|
10145
|
+
if (argList.length + rest.length >= len){
|
|
10146
|
+
return fn(...argList, ...rest)
|
|
10075
10147
|
}
|
|
10076
10148
|
|
|
10077
|
-
return partial(fn, ...[ ...
|
|
10149
|
+
return partial(fn, ...[ ...argList, ...rest ])
|
|
10078
10150
|
}
|
|
10079
10151
|
}
|
|
10080
10152
|
```
|
|
@@ -10092,7 +10164,7 @@ import { type } from './type.js'
|
|
|
10092
10164
|
const greet = (
|
|
10093
10165
|
salutation, title, firstName, lastName
|
|
10094
10166
|
) =>
|
|
10095
|
-
salutation
|
|
10167
|
+
[salutation, title, firstName, lastName]
|
|
10096
10168
|
|
|
10097
10169
|
test('happy', () => {
|
|
10098
10170
|
const canPassAnyNumberOfArguments = partial(
|
|
@@ -10104,8 +10176,8 @@ test('happy', () => {
|
|
|
10104
10176
|
|
|
10105
10177
|
expect(type(fn)).toBe('Function')
|
|
10106
10178
|
|
|
10107
|
-
expect(fn('bar')).
|
|
10108
|
-
expect(sayHelloRamda('foo', 'bar')).
|
|
10179
|
+
expect(fn('bar')).toStrictEqual(['Hello', 'Ms.', 'foo', 'bar'])
|
|
10180
|
+
expect(sayHelloRamda('foo', 'bar')).toStrictEqual(['Hello', 'Ms.', 'foo', 'bar'])
|
|
10109
10181
|
})
|
|
10110
10182
|
|
|
10111
10183
|
test('extra arguments are ignored', () => {
|
|
@@ -10118,7 +10190,7 @@ test('extra arguments are ignored', () => {
|
|
|
10118
10190
|
|
|
10119
10191
|
expect(fn(
|
|
10120
10192
|
'bar', 1, 2
|
|
10121
|
-
)).
|
|
10193
|
+
)).toStrictEqual(['Hello', 'Ms.', 'foo', 'bar'])
|
|
10122
10194
|
})
|
|
10123
10195
|
|
|
10124
10196
|
test('when array is input', () => {
|
|
@@ -10146,7 +10218,7 @@ test('ramda spec', () => {
|
|
|
10146
10218
|
const sayHello = partial(greet, 'Hello')
|
|
10147
10219
|
const sayHelloToMs = partial(sayHello, 'Ms.')
|
|
10148
10220
|
|
|
10149
|
-
expect(sayHelloToMs('Jane', 'Jones')).
|
|
10221
|
+
expect(sayHelloToMs('Jane', 'Jones')).toStrictEqual(['Hello', 'Ms.', 'Jane', 'Jones'])
|
|
10150
10222
|
})
|
|
10151
10223
|
```
|
|
10152
10224
|
|
|
@@ -10161,19 +10233,24 @@ import {partial} from 'rambda'
|
|
|
10161
10233
|
|
|
10162
10234
|
describe('R.partial', () => {
|
|
10163
10235
|
it('happy', () => {
|
|
10164
|
-
function
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10236
|
+
function fn(
|
|
10237
|
+
aString: string,
|
|
10238
|
+
aNumber: number,
|
|
10239
|
+
aBoolean: boolean,
|
|
10240
|
+
aNull: null
|
|
10169
10241
|
) {
|
|
10170
|
-
return
|
|
10242
|
+
return {aString, aNumber, aBoolean, aNull}
|
|
10171
10243
|
}
|
|
10172
10244
|
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
|
|
10245
|
+
// @ts-expect-error
|
|
10246
|
+
partial(fn, 1)
|
|
10247
|
+
|
|
10248
|
+
const fn1 = partial(fn, ['a'])
|
|
10249
|
+
partial(fn1, ['b'])
|
|
10250
|
+
|
|
10251
|
+
const fn2 = partial(fn1, [2])
|
|
10252
|
+
const result = fn2(true, null)
|
|
10253
|
+
result // $ExpectType { aString: string; aNumber: number; aBoolean: boolean; aNull: null; }
|
|
10177
10254
|
})
|
|
10178
10255
|
})
|
|
10179
10256
|
```
|
|
@@ -11318,10 +11395,10 @@ test('works with list as input and number as props - props to pick is a string',
|
|
|
11318
11395
|
test('with symbol', () => {
|
|
11319
11396
|
const symbolProp = Symbol('s')
|
|
11320
11397
|
expect(pick([ symbolProp ], { [ symbolProp ] : 'a' })).toMatchInlineSnapshot(`
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11398
|
+
{
|
|
11399
|
+
Symbol(s): "a",
|
|
11400
|
+
}
|
|
11401
|
+
`)
|
|
11325
11402
|
})
|
|
11326
11403
|
```
|
|
11327
11404
|
|
|
@@ -11674,7 +11751,7 @@ describe('R.pluck', () => {
|
|
|
11674
11751
|
|
|
11675
11752
|
```typescript
|
|
11676
11753
|
|
|
11677
|
-
prepend<T>(
|
|
11754
|
+
prepend<T>(xToPrepend: T, iterable: T[]): T[]
|
|
11678
11755
|
```
|
|
11679
11756
|
|
|
11680
11757
|
It adds element `x` at the beginning of `list`.
|
|
@@ -11686,8 +11763,10 @@ It adds element `x` at the beginning of `list`.
|
|
|
11686
11763
|
<summary>All TypeScript definitions</summary>
|
|
11687
11764
|
|
|
11688
11765
|
```typescript
|
|
11689
|
-
prepend<T>(
|
|
11690
|
-
prepend<T>(
|
|
11766
|
+
prepend<T>(xToPrepend: T, iterable: T[]): T[];
|
|
11767
|
+
prepend<T, U>(xToPrepend: T, iterable: IsFirstSubtypeOfSecond<T, U>[]) : U[];
|
|
11768
|
+
prepend<T>(xToPrepend: T): <U>(iterable: IsFirstSubtypeOfSecond<T, U>[]) => U[];
|
|
11769
|
+
prepend<T>(xToPrepend: T): (iterable: T[]) => T[];
|
|
11691
11770
|
```
|
|
11692
11771
|
|
|
11693
11772
|
</details>
|
|
@@ -11735,31 +11814,6 @@ test('with string instead of array', () => {
|
|
|
11735
11814
|
|
|
11736
11815
|
</details>
|
|
11737
11816
|
|
|
11738
|
-
<details>
|
|
11739
|
-
|
|
11740
|
-
<summary><strong>TypeScript</strong> test</summary>
|
|
11741
|
-
|
|
11742
|
-
```typescript
|
|
11743
|
-
import {prepend} from 'rambda'
|
|
11744
|
-
|
|
11745
|
-
const list = [1, 2, 3]
|
|
11746
|
-
|
|
11747
|
-
describe('R.prepend', () => {
|
|
11748
|
-
it('happy', () => {
|
|
11749
|
-
const result = prepend(4, list)
|
|
11750
|
-
|
|
11751
|
-
result // $ExpectType number[]
|
|
11752
|
-
})
|
|
11753
|
-
it('curried', () => {
|
|
11754
|
-
const result = prepend(4)(list)
|
|
11755
|
-
|
|
11756
|
-
result // $ExpectType number[]
|
|
11757
|
-
})
|
|
11758
|
-
})
|
|
11759
|
-
```
|
|
11760
|
-
|
|
11761
|
-
</details>
|
|
11762
|
-
|
|
11763
11817
|
[](#prepend)
|
|
11764
11818
|
|
|
11765
11819
|
### product
|
|
@@ -12721,6 +12775,96 @@ describe('R.reject with objects', () => {
|
|
|
12721
12775
|
|
|
12722
12776
|
[](#reject)
|
|
12723
12777
|
|
|
12778
|
+
### removeIndex
|
|
12779
|
+
|
|
12780
|
+
```typescript
|
|
12781
|
+
|
|
12782
|
+
removeIndex<T>(index: number, list: T[]): T[]
|
|
12783
|
+
```
|
|
12784
|
+
|
|
12785
|
+
It returns a copy of `list` input with removed `index`.
|
|
12786
|
+
|
|
12787
|
+
<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%20result%20%3D%20R.removeIndex(1%2C%20list)%0A%2F%2F%20%3D%3E%20%5B1%2C%203%2C%204%5D">Try this <strong>R.removeIndex</strong> example in Rambda REPL</a>
|
|
12788
|
+
|
|
12789
|
+
<details>
|
|
12790
|
+
|
|
12791
|
+
<summary>All TypeScript definitions</summary>
|
|
12792
|
+
|
|
12793
|
+
```typescript
|
|
12794
|
+
removeIndex<T>(index: number, list: T[]): T[];
|
|
12795
|
+
removeIndex(index: number): <T>(list: T[]) => T[];
|
|
12796
|
+
```
|
|
12797
|
+
|
|
12798
|
+
</details>
|
|
12799
|
+
|
|
12800
|
+
<details>
|
|
12801
|
+
|
|
12802
|
+
<summary><strong>R.removeIndex</strong> source</summary>
|
|
12803
|
+
|
|
12804
|
+
```javascript
|
|
12805
|
+
export function removeIndex(index, list){
|
|
12806
|
+
if (arguments.length === 1) return _list => removeIndex(index, _list)
|
|
12807
|
+
if (index <= 0) return list.slice(1)
|
|
12808
|
+
if (index >= list.length - 1) return list.slice(0, list.length - 1)
|
|
12809
|
+
|
|
12810
|
+
return [ ...list.slice(0, index), ...list.slice(index + 1) ]
|
|
12811
|
+
}
|
|
12812
|
+
```
|
|
12813
|
+
|
|
12814
|
+
</details>
|
|
12815
|
+
|
|
12816
|
+
<details>
|
|
12817
|
+
|
|
12818
|
+
<summary><strong>Tests</strong></summary>
|
|
12819
|
+
|
|
12820
|
+
```javascript
|
|
12821
|
+
import { removeIndex } from './removeIndex.js'
|
|
12822
|
+
|
|
12823
|
+
const list = [ 1, 2, 3, 4 ]
|
|
12824
|
+
|
|
12825
|
+
test('first or before first index', () => {
|
|
12826
|
+
expect(removeIndex(-2, list)).toEqual([ 2, 3, 4 ])
|
|
12827
|
+
expect(removeIndex(-2)(list)).toEqual([ 2, 3, 4 ])
|
|
12828
|
+
})
|
|
12829
|
+
|
|
12830
|
+
test('last or after last index', () => {
|
|
12831
|
+
expect(removeIndex(4, list)).toEqual([ 1, 2, 3 ])
|
|
12832
|
+
expect(removeIndex(10, list)).toEqual([ 1, 2, 3 ])
|
|
12833
|
+
})
|
|
12834
|
+
|
|
12835
|
+
test('middle index', () => {
|
|
12836
|
+
expect(removeIndex(1, list)).toEqual([ 1, 3, 4 ])
|
|
12837
|
+
expect(removeIndex(2, list)).toEqual([ 1, 2, 4 ])
|
|
12838
|
+
})
|
|
12839
|
+
```
|
|
12840
|
+
|
|
12841
|
+
</details>
|
|
12842
|
+
|
|
12843
|
+
<details>
|
|
12844
|
+
|
|
12845
|
+
<summary><strong>TypeScript</strong> test</summary>
|
|
12846
|
+
|
|
12847
|
+
```typescript
|
|
12848
|
+
import {removeIndex} from 'rambda'
|
|
12849
|
+
|
|
12850
|
+
describe('R.removeIndex', () => {
|
|
12851
|
+
it('happy', () => {
|
|
12852
|
+
const result = removeIndex(1, [1, 2, 3])
|
|
12853
|
+
|
|
12854
|
+
result // $ExpectType number[]
|
|
12855
|
+
})
|
|
12856
|
+
it('curried', () => {
|
|
12857
|
+
const result = removeIndex(1)([1, 2, 3])
|
|
12858
|
+
|
|
12859
|
+
result // $ExpectType number[]
|
|
12860
|
+
})
|
|
12861
|
+
})
|
|
12862
|
+
```
|
|
12863
|
+
|
|
12864
|
+
</details>
|
|
12865
|
+
|
|
12866
|
+
[](#removeIndex)
|
|
12867
|
+
|
|
12724
12868
|
### repeat
|
|
12725
12869
|
|
|
12726
12870
|
```typescript
|
|
@@ -15126,30 +15270,6 @@ test('happy', () => {
|
|
|
15126
15270
|
|
|
15127
15271
|
</details>
|
|
15128
15272
|
|
|
15129
|
-
<details>
|
|
15130
|
-
|
|
15131
|
-
<summary><strong>TypeScript</strong> test</summary>
|
|
15132
|
-
|
|
15133
|
-
```typescript
|
|
15134
|
-
import {toPairs} from 'rambda'
|
|
15135
|
-
|
|
15136
|
-
const obj = {
|
|
15137
|
-
a: 1,
|
|
15138
|
-
b: 2,
|
|
15139
|
-
c: [3, 4],
|
|
15140
|
-
}
|
|
15141
|
-
|
|
15142
|
-
describe('R.toPairs', () => {
|
|
15143
|
-
it('happy', () => {
|
|
15144
|
-
const result = toPairs(obj)
|
|
15145
|
-
|
|
15146
|
-
result // $ExpectType (["b", number] | ["a", number] | ["c", number[]])[]
|
|
15147
|
-
})
|
|
15148
|
-
})
|
|
15149
|
-
```
|
|
15150
|
-
|
|
15151
|
-
</details>
|
|
15152
|
-
|
|
15153
15273
|
[](#toPairs)
|
|
15154
15274
|
|
|
15155
15275
|
### toString
|
|
@@ -17181,13 +17301,13 @@ describe('R.zipObj', () => {
|
|
|
17181
17301
|
it('happy', () => {
|
|
17182
17302
|
// this is wrong since 24.10.2020 `@types/ramda` changes
|
|
17183
17303
|
const result = zipObj(['a', 'b', 'c', 'd'], [1, 2, 3])
|
|
17184
|
-
result
|
|
17304
|
+
;[result.a, result.b, result.c, result.d] // $ExpectType number[]
|
|
17185
17305
|
})
|
|
17186
17306
|
it('imported from @types/ramda', () => {
|
|
17187
17307
|
const result = zipObj(['a', 'b', 'c'], [1, 2, 3])
|
|
17188
17308
|
const curriedResult = zipObj(['a', 'b', 'c'])([1, 2, 3])
|
|
17189
|
-
result // $ExpectType
|
|
17190
|
-
curriedResult // $ExpectType
|
|
17309
|
+
;[result.a, result.b, result.c] // $ExpectType number[]
|
|
17310
|
+
;[curriedResult.a, curriedResult.b, curriedResult.c] // $ExpectType number[]
|
|
17191
17311
|
})
|
|
17192
17312
|
})
|
|
17193
17313
|
```
|
|
@@ -17307,6 +17427,44 @@ describe('R.zipWith', () => {
|
|
|
17307
17427
|
|
|
17308
17428
|
## ❯ CHANGELOG
|
|
17309
17429
|
|
|
17430
|
+
8.5.0
|
|
17431
|
+
|
|
17432
|
+
- Revert changes in `R.anyPass` introduced in `8.4.0` release. The reason is that the change was breaking the library older than `5.2.0` TypeScript.
|
|
17433
|
+
|
|
17434
|
+
- Wrong `R.partial` TS definition - [Issue #705](https://github.com/selfrefactor/rambda/issues/705)
|
|
17435
|
+
|
|
17436
|
+
- Add `R.dropRepeatsBy`
|
|
17437
|
+
|
|
17438
|
+
- Add `R.empty`
|
|
17439
|
+
|
|
17440
|
+
- Add `R.eqBy`
|
|
17441
|
+
|
|
17442
|
+
- Add `R.forEachObjIndexed`
|
|
17443
|
+
|
|
17444
|
+
8.4.0
|
|
17445
|
+
|
|
17446
|
+
- Add `R.dissocPath`
|
|
17447
|
+
|
|
17448
|
+
- Fix TS definitions of `R.head/R.last` and add missing handle of empty string
|
|
17449
|
+
|
|
17450
|
+
- Add `R.removeIndex` - method was before only in `Rambdax`, but now since `R.dissocPath` is using it, it is added to main library.
|
|
17451
|
+
|
|
17452
|
+
- Allow `R.omit` to pass numbers as part of properties to omit, i.e. `R.omit(['a', 1], {a: {1: 1, 2: 2}})`
|
|
17453
|
+
|
|
17454
|
+
- R.keys always returns strings - [MR #700](https://github.com/selfrefactor/rambda/pull/700)
|
|
17455
|
+
|
|
17456
|
+
- Improve `R.prepend/R.append` type interference - [MR #699](https://github.com/selfrefactor/rambda/pull/699)
|
|
17457
|
+
|
|
17458
|
+
- Change `R.reduce` TS definitions so index is always received - [MR #696](https://github.com/selfrefactor/rambda/pull/696)
|
|
17459
|
+
|
|
17460
|
+
- Functions as a type guard in `R.anyPass` TS definitions - [MR #695](https://github.com/selfrefactor/rambda/pull/695)
|
|
17461
|
+
|
|
17462
|
+
- Fix R.append's curried type - [MR #694](https://github.com/selfrefactor/rambda/pull/694)
|
|
17463
|
+
|
|
17464
|
+
- Fix cannot compare errors in `Deno` with `R.equals` - [Issue #704](https://github.com/selfrefactor/rambda/issues/704).
|
|
17465
|
+
|
|
17466
|
+
- Fix cannot compare `BigInt` with `R.equals`
|
|
17467
|
+
|
|
17310
17468
|
8.3.0
|
|
17311
17469
|
|
|
17312
17470
|
Add the following methods:
|
|
@@ -17613,12 +17771,14 @@ Fix wrong versions in changelog
|
|
|
17613
17771
|
|
|
17614
17772
|
## ❯ Additional info
|
|
17615
17773
|
|
|
17616
|
-
> Most influential contributors
|
|
17774
|
+
> Most influential contributors(in alphabetical order)
|
|
17617
17775
|
|
|
17618
17776
|
- [@farwayer](https://github.com/farwayer) - improving performance in R.find, R.filter; give the idea how to make benchmarks more reliable;
|
|
17619
17777
|
|
|
17620
17778
|
- [@thejohnfreeman](https://github.com/thejohnfreeman) - add R.assoc, R.chain;
|
|
17621
17779
|
|
|
17780
|
+
- [@peeja](https://github.com/peeja) - add several methods and fix mutiple issues; provides great MR documentation
|
|
17781
|
+
|
|
17622
17782
|
- [@helmuthdu](https://github.com/helmuthdu) - add R.clone; help improve code style;
|
|
17623
17783
|
|
|
17624
17784
|
- [@jpgorman](https://github.com/jpgorman) - add R.zip, R.reject, R.without, R.addIndex;
|