effect 3.14.5 → 3.14.7
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/dist/cjs/JSONSchema.js +5 -4
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/MutableHashSet.js +434 -0
- package/dist/cjs/MutableHashSet.js.map +1 -1
- package/dist/cjs/internal/metric/hook.js +1 -1
- package/dist/cjs/internal/metric/hook.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/MutableHashSet.d.ts +467 -12
- package/dist/dts/MutableHashSet.d.ts.map +1 -1
- package/dist/dts/index.d.ts +91 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/JSONSchema.js +5 -4
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/MutableHashSet.js +434 -0
- package/dist/esm/MutableHashSet.js.map +1 -1
- package/dist/esm/index.js +91 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/metric/hook.js +1 -1
- package/dist/esm/internal/metric/hook.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/JSONSchema.ts +5 -4
- package/src/MutableHashSet.ts +572 -16
- package/src/index.ts +91 -0
- package/src/internal/metric/hook.ts +1 -1
- package/src/internal/version.ts +1 -1
package/src/MutableHashSet.ts
CHANGED
|
@@ -1,4 +1,95 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* # MutableHashSet
|
|
3
|
+
*
|
|
4
|
+
* A mutable `MutableHashSet` provides a collection of unique values with
|
|
5
|
+
* efficient lookup, insertion and removal. Unlike its immutable sibling
|
|
6
|
+
* {@link module:HashSet}, a `MutableHashSet` can be modified in-place;
|
|
7
|
+
* operations like add, remove, and clear directly modify the original set
|
|
8
|
+
* rather than creating a new one. This mutability offers benefits like improved
|
|
9
|
+
* performance in scenarios where you need to build or modify a set
|
|
10
|
+
* incrementally.
|
|
11
|
+
*
|
|
12
|
+
* ## What Problem Does It Solve?
|
|
13
|
+
*
|
|
14
|
+
* `MutableHashSet` solves the problem of maintaining an unsorted collection
|
|
15
|
+
* where each value appears exactly once, with fast operations for checking
|
|
16
|
+
* membership and adding/removing values, in contexts where mutability is
|
|
17
|
+
* preferred for performance or implementation simplicity.
|
|
18
|
+
*
|
|
19
|
+
* ## When to Use
|
|
20
|
+
*
|
|
21
|
+
* Use `MutableHashSet` when you need:
|
|
22
|
+
*
|
|
23
|
+
* - A collection with no duplicate values
|
|
24
|
+
* - Efficient membership testing (**`O(1)`** average complexity)
|
|
25
|
+
* - In-place modifications for better performance
|
|
26
|
+
* - A set that will be built or modified incrementally
|
|
27
|
+
* - Local mutability in otherwise immutable code
|
|
28
|
+
*
|
|
29
|
+
* ## Advanced Features
|
|
30
|
+
*
|
|
31
|
+
* MutableHashSet provides operations for:
|
|
32
|
+
*
|
|
33
|
+
* - Adding and removing elements with direct mutation
|
|
34
|
+
* - Checking for element existence
|
|
35
|
+
* - Clearing all elements at once
|
|
36
|
+
* - Converting to/from other collection types
|
|
37
|
+
*
|
|
38
|
+
* ## Performance Characteristics
|
|
39
|
+
*
|
|
40
|
+
* - **Lookup** operations ({@link module:MutableHashSet.has}): **`O(1)`** average
|
|
41
|
+
* time complexity
|
|
42
|
+
* - **Insertion** operations ({@link module:MutableHashSet.add}): **`O(1)`**
|
|
43
|
+
* average time complexity
|
|
44
|
+
* - **Removal** operations ({@link module:MutableHashSet.remove}): **`O(1)`**
|
|
45
|
+
* average time complexity
|
|
46
|
+
* - **Iteration**: **`O(n)`** where n is the size of the set
|
|
47
|
+
*
|
|
48
|
+
* The MutableHashSet data structure implements the following traits:
|
|
49
|
+
*
|
|
50
|
+
* - {@link Iterable}: allows iterating over the values in the set
|
|
51
|
+
* - {@link Pipeable}: allows chaining operations with the pipe operator
|
|
52
|
+
* - {@link Inspectable}: allows inspecting the contents of the set
|
|
53
|
+
*
|
|
54
|
+
* ## Operations Reference
|
|
55
|
+
*
|
|
56
|
+
* | Category | Operation | Description | Complexity |
|
|
57
|
+
* | ------------ | ------------------------------------------ | ----------------------------------- | ---------- |
|
|
58
|
+
* | constructors | {@link module:MutableHashSet.empty} | Creates an empty MutableHashSet | O(1) |
|
|
59
|
+
* | constructors | {@link module:MutableHashSet.fromIterable} | Creates a set from an iterable | O(n) |
|
|
60
|
+
* | constructors | {@link module:MutableHashSet.make} | Creates a set from multiple values | O(n) |
|
|
61
|
+
* | | | | |
|
|
62
|
+
* | elements | {@link module:MutableHashSet.has} | Checks if a value exists in the set | O(1) avg |
|
|
63
|
+
* | elements | {@link module:MutableHashSet.add} | Adds a value to the set | O(1) avg |
|
|
64
|
+
* | elements | {@link module:MutableHashSet.remove} | Removes a value from the set | O(1) avg |
|
|
65
|
+
* | elements | {@link module:MutableHashSet.size} | Gets the number of elements | O(1) |
|
|
66
|
+
* | elements | {@link module:MutableHashSet.clear} | Removes all values from the set | O(1) |
|
|
67
|
+
*
|
|
68
|
+
* ## Notes
|
|
69
|
+
*
|
|
70
|
+
* ### Mutability Considerations:
|
|
71
|
+
*
|
|
72
|
+
* Unlike most data structures in the Effect ecosystem, `MutableHashSet` is
|
|
73
|
+
* mutable. This means that operations like `add`, `remove`, and `clear` modify
|
|
74
|
+
* the original set rather than creating a new one. This can lead to more
|
|
75
|
+
* efficient code in some scenarios, but requires careful handling to avoid
|
|
76
|
+
* unexpected side effects.
|
|
77
|
+
*
|
|
78
|
+
* ### When to Choose `MutableHashSet` vs {@link module:HashSet}:
|
|
79
|
+
*
|
|
80
|
+
* - Use `MutableHashSet` when you need to build or modify a set incrementally and
|
|
81
|
+
* performance is a priority
|
|
82
|
+
* - Use `HashSet` when you want immutability guarantees and functional
|
|
83
|
+
* programming patterns
|
|
84
|
+
* - Consider using {@link module:HashSet}'s bounded mutation context (via
|
|
85
|
+
* {@link module:HashSet.beginMutation}, {@link module:HashSet.endMutation}, and
|
|
86
|
+
* {@link module:HashSet.mutate} methods) when you need temporary mutability
|
|
87
|
+
* within an otherwise immutable context - this approach might be sufficient
|
|
88
|
+
* for many use cases without requiring a separate `MutableHashSet`
|
|
89
|
+
* - `MutableHashSet` is often useful for local operations where the mutability is
|
|
90
|
+
* contained and doesn't leak into the broader application
|
|
91
|
+
*
|
|
92
|
+
* @module MutableHashSet
|
|
2
93
|
* @since 2.0.0
|
|
3
94
|
*/
|
|
4
95
|
import * as Dual from "./Function.js"
|
|
@@ -29,7 +120,8 @@ export interface MutableHashSet<out V> extends Iterable<V>, Pipeable, Inspectabl
|
|
|
29
120
|
const MutableHashSetProto: Omit<MutableHashSet<unknown>, "keyMap"> = {
|
|
30
121
|
[TypeId]: TypeId,
|
|
31
122
|
[Symbol.iterator](this: MutableHashSet<unknown>): Iterator<unknown> {
|
|
32
|
-
return Array.from(this.keyMap)
|
|
123
|
+
return Array.from(this.keyMap)
|
|
124
|
+
.map(([_]) => _)[Symbol.iterator]()
|
|
33
125
|
},
|
|
34
126
|
toString() {
|
|
35
127
|
return format(this.toJSON())
|
|
@@ -48,48 +140,322 @@ const MutableHashSetProto: Omit<MutableHashSet<unknown>, "keyMap"> = {
|
|
|
48
140
|
}
|
|
49
141
|
}
|
|
50
142
|
|
|
51
|
-
const fromHashMap = <V>(
|
|
143
|
+
const fromHashMap = <V>(
|
|
144
|
+
keyMap: MutableHashMap.MutableHashMap<V, boolean>
|
|
145
|
+
): MutableHashSet<V> => {
|
|
52
146
|
const set = Object.create(MutableHashSetProto)
|
|
53
147
|
set.keyMap = keyMap
|
|
54
148
|
return set
|
|
55
149
|
}
|
|
56
150
|
|
|
57
151
|
/**
|
|
152
|
+
* Creates an empty mutable hash set.
|
|
153
|
+
*
|
|
154
|
+
* This function initializes and returns an empty `MutableHashSet` instance,
|
|
155
|
+
* which allows for efficient storage and manipulation of unique elements.
|
|
156
|
+
*
|
|
157
|
+
* Time complexity: **`O(1)`**
|
|
158
|
+
*
|
|
159
|
+
* @memberof MutableHashSet
|
|
58
160
|
* @since 2.0.0
|
|
59
161
|
* @category constructors
|
|
162
|
+
* @example
|
|
163
|
+
*
|
|
164
|
+
* ```ts
|
|
165
|
+
* import { MutableHashSet } from "effect"
|
|
166
|
+
*
|
|
167
|
+
* type T = unknown // replace with your type
|
|
168
|
+
*
|
|
169
|
+
* // in places where the type can't be inferred, replace with your type
|
|
170
|
+
* const set: MutableHashSet.MutableHashSet<T> = MutableHashSet.empty<T>()
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @template K - The type of the elements to be stored in the hash set. Defaults
|
|
174
|
+
* to `never` if not specified.
|
|
175
|
+
* @returns A new mutable instance of `MutableHashSet` containing no elements
|
|
176
|
+
* for the specified type `K`.
|
|
177
|
+
* @see Other `MutableHashSet` constructors are {@link module:MutableHashSet.make} {@link module:MutableHashSet.fromIterable}
|
|
60
178
|
*/
|
|
61
179
|
export const empty = <K = never>(): MutableHashSet<K> => fromHashMap(MutableHashMap.empty())
|
|
62
180
|
|
|
63
181
|
/**
|
|
64
182
|
* Creates a new `MutableHashSet` from an iterable collection of values.
|
|
183
|
+
* Duplicate values are omitted.
|
|
184
|
+
*
|
|
185
|
+
* Time complexity: **`O(n)`** where n is the number of elements in the iterable
|
|
186
|
+
*
|
|
187
|
+
* Creating a `MutableHashSet` from an {@link Array}
|
|
188
|
+
*
|
|
189
|
+
* ```ts
|
|
190
|
+
* import { MutableHashSet } from "effect"
|
|
191
|
+
*
|
|
192
|
+
* const array: Iterable<number> = [1, 2, 3, 4, 5, 1, 2, 3] // Array<T> is also Iterable<T>
|
|
193
|
+
* const mutableHashSet: MutableHashSet.MutableHashSet<number> =
|
|
194
|
+
* MutableHashSet.fromIterable(array)
|
|
195
|
+
*
|
|
196
|
+
* console.log(
|
|
197
|
+
* // MutableHashSet.MutableHashSet<T> is also an Iterable<T>
|
|
198
|
+
* Array.from(mutableHashSet)
|
|
199
|
+
* ) // Output: [1, 2, 3, 4, 5]
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* Creating a `MutableHashSet` from a {@link Set}
|
|
203
|
+
*
|
|
204
|
+
* ```ts
|
|
205
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
206
|
+
*
|
|
207
|
+
* console.log(
|
|
208
|
+
* pipe(
|
|
209
|
+
* // Set<string> is an Iterable<string>
|
|
210
|
+
* new Set(["apple", "banana", "orange", "apple"]),
|
|
211
|
+
* // constructs MutableHashSet from an Iterable Set
|
|
212
|
+
* MutableHashSet.fromIterable,
|
|
213
|
+
* // since MutableHashSet it is itself an Iterable, we can pass it to other functions expecting an Iterable
|
|
214
|
+
* Array.from
|
|
215
|
+
* )
|
|
216
|
+
* ) // Output: ["apple", "banana", "orange"]
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* Creating a `MutableHashSet` from a {@link Generator}
|
|
220
|
+
*
|
|
221
|
+
* ```ts
|
|
222
|
+
* import { MutableHashSet } from "effect"
|
|
223
|
+
*
|
|
224
|
+
* // Generator functions return iterables
|
|
225
|
+
* function* fibonacci(n: number): Generator<number, void, never> {
|
|
226
|
+
* let [a, b] = [0, 1]
|
|
227
|
+
* for (let i = 0; i < n; i++) {
|
|
228
|
+
* yield a
|
|
229
|
+
* ;[a, b] = [b, a + b]
|
|
230
|
+
* }
|
|
231
|
+
* }
|
|
232
|
+
*
|
|
233
|
+
* // Create a MutableHashSet from the first 10 Fibonacci numbers
|
|
234
|
+
* const fibonacciSet = MutableHashSet.fromIterable(fibonacci(10))
|
|
235
|
+
*
|
|
236
|
+
* console.log(Array.from(fibonacciSet))
|
|
237
|
+
* // Outputs: [0, 1, 2, 3, 5, 8, 13, 21, 34] but in unsorted order
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* Creating a `MutableHashSet` from another {@link module:MutableHashSet}
|
|
241
|
+
*
|
|
242
|
+
* ```ts
|
|
243
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
244
|
+
*
|
|
245
|
+
* console.log(
|
|
246
|
+
* pipe(
|
|
247
|
+
* MutableHashSet.make(1, 2, 3, 4),
|
|
248
|
+
* MutableHashSet.fromIterable,
|
|
249
|
+
* Array.from
|
|
250
|
+
* )
|
|
251
|
+
* ) // Output: [1, 2, 3, 4]
|
|
252
|
+
* ```
|
|
253
|
+
*
|
|
254
|
+
* Creating a `MutableHashSet` from an {@link module:HashSet}
|
|
255
|
+
*
|
|
256
|
+
* ```ts
|
|
257
|
+
* import { HashSet, MutableHashSet, pipe } from "effect"
|
|
258
|
+
*
|
|
259
|
+
* console.log(
|
|
260
|
+
* pipe(
|
|
261
|
+
* HashSet.make(1, 2, 3, 4), // it works also with its immutable HashSet sibling
|
|
262
|
+
* MutableHashSet.fromIterable,
|
|
263
|
+
* Array.from
|
|
264
|
+
* )
|
|
265
|
+
* ) // Output: [1, 2, 3, 4]
|
|
266
|
+
* ```
|
|
267
|
+
*
|
|
268
|
+
* Creating a `MutableHashSet` from other Effect's data structures like
|
|
269
|
+
* {@link Chunk}
|
|
65
270
|
*
|
|
271
|
+
* ```ts
|
|
272
|
+
* import { Chunk, MutableHashSet, pipe } from "effect"
|
|
273
|
+
*
|
|
274
|
+
* console.log(
|
|
275
|
+
* pipe(
|
|
276
|
+
* Chunk.make(1, 2, 3, 4), // Chunk is also an Iterable<T>
|
|
277
|
+
* MutableHashSet.fromIterable,
|
|
278
|
+
* Array.from
|
|
279
|
+
* )
|
|
280
|
+
* ) // Outputs: [1, 2, 3, 4]
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* @memberof MutableHashSet
|
|
66
284
|
* @since 2.0.0
|
|
67
285
|
* @category constructors
|
|
286
|
+
* @template K - The type of elements to be stored in the resulting
|
|
287
|
+
* `MutableHashSet`.
|
|
288
|
+
* @param keys - An `Iterable` collection containing the keys to be added to the
|
|
289
|
+
* `MutableHashSet`.
|
|
290
|
+
* @returns A new `MutableHashSet` containing just the unique elements from the
|
|
291
|
+
* provided iterable.
|
|
292
|
+
* @see Other `MutableHashSet` constructors are {@link module:MutableHashSet.empty} {@link module:MutableHashSet.make}
|
|
68
293
|
*/
|
|
69
294
|
export const fromIterable = <K = never>(keys: Iterable<K>): MutableHashSet<K> =>
|
|
70
|
-
fromHashMap(
|
|
295
|
+
fromHashMap(
|
|
296
|
+
MutableHashMap.fromIterable(Array.from(keys).map((k) => [k, true]))
|
|
297
|
+
)
|
|
71
298
|
|
|
72
299
|
/**
|
|
300
|
+
* Construct a new `MutableHashSet` from a variable number of values.
|
|
301
|
+
*
|
|
302
|
+
* Time complexity: **`O(n)`** where n is the number of elements
|
|
303
|
+
*
|
|
304
|
+
* @memberof MutableHashSet
|
|
73
305
|
* @since 2.0.0
|
|
74
306
|
* @category constructors
|
|
307
|
+
* @example
|
|
308
|
+
*
|
|
309
|
+
* ```ts
|
|
310
|
+
* import { Equal, Hash, MutableHashSet } from "effect"
|
|
311
|
+
* import assert from "node:assert/strict"
|
|
312
|
+
*
|
|
313
|
+
* class Character implements Equal.Equal {
|
|
314
|
+
* readonly name: string
|
|
315
|
+
* readonly trait: string
|
|
316
|
+
*
|
|
317
|
+
* constructor(name: string, trait: string) {
|
|
318
|
+
* this.name = name
|
|
319
|
+
* this.trait = trait
|
|
320
|
+
* }
|
|
321
|
+
*
|
|
322
|
+
* // Define equality based on name, and trait
|
|
323
|
+
* [Equal.symbol](that: Equal.Equal): boolean {
|
|
324
|
+
* if (that instanceof Character) {
|
|
325
|
+
* return (
|
|
326
|
+
* Equal.equals(this.name, that.name) &&
|
|
327
|
+
* Equal.equals(this.trait, that.trait)
|
|
328
|
+
* )
|
|
329
|
+
* }
|
|
330
|
+
* return false
|
|
331
|
+
* }
|
|
332
|
+
*
|
|
333
|
+
* // Generate a hash code based on the sum of the character's name and trait
|
|
334
|
+
* [Hash.symbol](): number {
|
|
335
|
+
* return Hash.hash(this.name + this.trait)
|
|
336
|
+
* }
|
|
337
|
+
*
|
|
338
|
+
* static readonly of = (name: string, trait: string): Character => {
|
|
339
|
+
* return new Character(name, trait)
|
|
340
|
+
* }
|
|
341
|
+
* }
|
|
342
|
+
*
|
|
343
|
+
* const mutableCharacterHashSet = MutableHashSet.make(
|
|
344
|
+
* Character.of("Alice", "Curious"),
|
|
345
|
+
* Character.of("Alice", "Curious"),
|
|
346
|
+
* Character.of("White Rabbit", "Always late"),
|
|
347
|
+
* Character.of("Mad Hatter", "Tea enthusiast")
|
|
348
|
+
* )
|
|
349
|
+
*
|
|
350
|
+
* assert.equal(
|
|
351
|
+
* MutableHashSet.has(
|
|
352
|
+
* mutableCharacterHashSet,
|
|
353
|
+
* Character.of("Alice", "Curious")
|
|
354
|
+
* ),
|
|
355
|
+
* true
|
|
356
|
+
* )
|
|
357
|
+
* assert.equal(
|
|
358
|
+
* MutableHashSet.has(
|
|
359
|
+
* mutableCharacterHashSet,
|
|
360
|
+
* Character.of("Fluffy", "Kind")
|
|
361
|
+
* ),
|
|
362
|
+
* false
|
|
363
|
+
* )
|
|
364
|
+
* ```
|
|
365
|
+
*
|
|
366
|
+
* @see Other `MutableHashSet` constructors are {@link module:MutableHashSet.fromIterable} {@link module:MutableHashSet.empty}
|
|
75
367
|
*/
|
|
76
368
|
export const make = <Keys extends ReadonlyArray<unknown>>(
|
|
77
369
|
...keys: Keys
|
|
78
370
|
): MutableHashSet<Keys[number]> => fromIterable(keys)
|
|
79
371
|
|
|
80
372
|
/**
|
|
373
|
+
* **Checks** whether the `MutableHashSet` contains the given element, and
|
|
374
|
+
* **adds** it if not.
|
|
375
|
+
*
|
|
376
|
+
* Time complexity: **`O(1)`** average
|
|
377
|
+
*
|
|
378
|
+
* **Syntax**
|
|
379
|
+
*
|
|
380
|
+
* ```ts
|
|
381
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
382
|
+
*
|
|
383
|
+
* // with data-last, a.k.a. pipeable API
|
|
384
|
+
* pipe(
|
|
385
|
+
* MutableHashSet.empty(),
|
|
386
|
+
* MutableHashSet.add(0),
|
|
387
|
+
* MutableHashSet.add(0)
|
|
388
|
+
* )
|
|
389
|
+
*
|
|
390
|
+
* // or piped with the pipe function
|
|
391
|
+
* MutableHashSet.empty().pipe(MutableHashSet.add(0))
|
|
392
|
+
*
|
|
393
|
+
* // or with data-first API
|
|
394
|
+
* MutableHashSet.add(MutableHashSet.empty(), 0)
|
|
395
|
+
* ```
|
|
396
|
+
*
|
|
397
|
+
* @memberof MutableHashSet
|
|
81
398
|
* @since 2.0.0
|
|
82
399
|
* @category elements
|
|
400
|
+
* @see Other `MutableHashSet` elements are {@link module:MutableHashSet.remove} {@link module:MutableHashSet.size} {@link module:MutableHashSet.clear} {@link module:MutableHashSet.has}
|
|
83
401
|
*/
|
|
84
402
|
export const add: {
|
|
85
403
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
404
|
+
* `data-last` a.k.a. `pipeable` API
|
|
405
|
+
*
|
|
406
|
+
* ```ts
|
|
407
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
408
|
+
* import assert from "node:assert/strict"
|
|
409
|
+
*
|
|
410
|
+
* const mutableHashSet = pipe(
|
|
411
|
+
* MutableHashSet.empty<number>(), // MutableHashSet.MutableHashSet<number>
|
|
412
|
+
* MutableHashSet.add(0),
|
|
413
|
+
* MutableHashSet.add(1),
|
|
414
|
+
* MutableHashSet.add(1),
|
|
415
|
+
* MutableHashSet.add(2)
|
|
416
|
+
* )
|
|
417
|
+
*
|
|
418
|
+
* assert.deepStrictEqual(
|
|
419
|
+
* Array.from(mutableHashSet), // remember that MutableHashSet is also an Iterable
|
|
420
|
+
* Array.of(0, 1, 2)
|
|
421
|
+
* )
|
|
422
|
+
* ```
|
|
423
|
+
*
|
|
424
|
+
* @template V - The type of elements stored in the `MutableHashSet`.
|
|
425
|
+
* @param key - The key to be added to the `MutableHashSet` if not already
|
|
426
|
+
* present.
|
|
427
|
+
* @returns A function that accepts a `MutableHashSet` and returns the
|
|
428
|
+
* reference of the updated `MutableHashSet` including the key.
|
|
88
429
|
*/
|
|
89
430
|
<V>(key: V): (self: MutableHashSet<V>) => MutableHashSet<V>
|
|
431
|
+
|
|
90
432
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
433
|
+
* `data-first` API
|
|
434
|
+
*
|
|
435
|
+
* ```ts
|
|
436
|
+
* import { MutableHashSet } from "effect"
|
|
437
|
+
* import assert from "node:assert/strict"
|
|
438
|
+
*
|
|
439
|
+
* const empty = MutableHashSet.empty<number>()
|
|
440
|
+
* const withZero = MutableHashSet.add(empty, 0)
|
|
441
|
+
* const withOne = MutableHashSet.add(withZero, 1)
|
|
442
|
+
* const withTwo = MutableHashSet.add(withOne, 2)
|
|
443
|
+
* const withTwoTwo = MutableHashSet.add(withTwo, 2)
|
|
444
|
+
*
|
|
445
|
+
* assert(Object.is(withTwoTwo, empty)) // proof that it does mutate the original set
|
|
446
|
+
*
|
|
447
|
+
* assert.deepStrictEqual(
|
|
448
|
+
* Array.from(withTwoTwo), // remember that MutableHashSet is also an Iterable
|
|
449
|
+
* Array.of(0, 1, 2)
|
|
450
|
+
* )
|
|
451
|
+
* ```
|
|
452
|
+
*
|
|
453
|
+
* @template V - The type of elements stored in the `MutableHashSet`.
|
|
454
|
+
* @param self - The `MutableHashSet` instance from which the key should be
|
|
455
|
+
* added to.
|
|
456
|
+
* @param key - The key to be added to the `MutableHashSet` if not already
|
|
457
|
+
* present.
|
|
458
|
+
* @returns The reference of the updated `MutableHashSet` including the key.
|
|
93
459
|
*/
|
|
94
460
|
<V>(self: MutableHashSet<V>, key: V): MutableHashSet<V>
|
|
95
461
|
} = Dual.dual<
|
|
@@ -98,18 +464,72 @@ export const add: {
|
|
|
98
464
|
>(2, (self, key) => (MutableHashMap.set(self.keyMap, key, true), self))
|
|
99
465
|
|
|
100
466
|
/**
|
|
467
|
+
* Checks if the specified value exists in the `MutableHashSet`.
|
|
468
|
+
*
|
|
469
|
+
* Time complexity: `O(1)` average
|
|
470
|
+
*
|
|
471
|
+
* **Syntax**
|
|
472
|
+
*
|
|
473
|
+
* ```ts
|
|
474
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
475
|
+
* import assert from "node:assert/strict"
|
|
476
|
+
*
|
|
477
|
+
* assert.equal(
|
|
478
|
+
* // with `data-last`, a.k.a. `pipeable` API
|
|
479
|
+
* pipe(MutableHashSet.make(0, 1, 2), MutableHashSet.has(3)),
|
|
480
|
+
* false
|
|
481
|
+
* )
|
|
482
|
+
*
|
|
483
|
+
* assert.equal(
|
|
484
|
+
* // or piped with the pipe function
|
|
485
|
+
* MutableHashSet.make(0, 1, 2).pipe(MutableHashSet.has(3)),
|
|
486
|
+
* false
|
|
487
|
+
* )
|
|
488
|
+
*
|
|
489
|
+
* assert.equal(
|
|
490
|
+
* // or with `data-first` API
|
|
491
|
+
* MutableHashSet.has(MutableHashSet.make(0, 1, 2), 3),
|
|
492
|
+
* false
|
|
493
|
+
* )
|
|
494
|
+
* ```
|
|
495
|
+
*
|
|
496
|
+
* @memberof MutableHashSet
|
|
101
497
|
* @since 2.0.0
|
|
102
498
|
* @category elements
|
|
499
|
+
* @see Other `MutableHashSet` elements are {@link module:MutableHashSet.add} {@link module:MutableHashSet.remove} {@link module:MutableHashSet.size} {@link module:MutableHashSet.clear}
|
|
103
500
|
*/
|
|
104
501
|
export const has: {
|
|
105
502
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
503
|
+
* `data-last` a.k.a. `pipeable` API
|
|
504
|
+
*
|
|
505
|
+
* ```ts
|
|
506
|
+
* import * as assert from "node:assert/strict"
|
|
507
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
508
|
+
*
|
|
509
|
+
* const set = MutableHashSet.make(0, 1, 2)
|
|
510
|
+
*
|
|
511
|
+
* assert.equal(pipe(set, MutableHashSet.has(0)), true)
|
|
512
|
+
* assert.equal(pipe(set, MutableHashSet.has(1)), true)
|
|
513
|
+
* assert.equal(pipe(set, MutableHashSet.has(2)), true)
|
|
514
|
+
* assert.equal(pipe(set, MutableHashSet.has(3)), false)
|
|
515
|
+
* ```
|
|
108
516
|
*/
|
|
109
517
|
<V>(key: V): (self: MutableHashSet<V>) => boolean
|
|
518
|
+
|
|
110
519
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
520
|
+
* `data-first` API
|
|
521
|
+
*
|
|
522
|
+
* ```ts
|
|
523
|
+
* import * as assert from "node:assert/strict"
|
|
524
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
525
|
+
*
|
|
526
|
+
* const set = MutableHashSet.make(0, 1, 2)
|
|
527
|
+
*
|
|
528
|
+
* assert.equal(MutableHashSet.has(set, 0), true)
|
|
529
|
+
* assert.equal(MutableHashSet.has(set, 1), true)
|
|
530
|
+
* assert.equal(MutableHashSet.has(set, 2), true)
|
|
531
|
+
* assert.equal(MutableHashSet.has(set, 3), false)
|
|
532
|
+
* ```
|
|
113
533
|
*/
|
|
114
534
|
<V>(self: MutableHashSet<V>, key: V): boolean
|
|
115
535
|
} = Dual.dual<
|
|
@@ -118,18 +538,102 @@ export const has: {
|
|
|
118
538
|
>(2, (self, key) => MutableHashMap.has(self.keyMap, key))
|
|
119
539
|
|
|
120
540
|
/**
|
|
541
|
+
* Removes a value from the `MutableHashSet`.
|
|
542
|
+
*
|
|
543
|
+
* Time complexity: **`O(1)`** average
|
|
544
|
+
*
|
|
545
|
+
* **Syntax**
|
|
546
|
+
*
|
|
547
|
+
* ```ts
|
|
548
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
549
|
+
* import assert from "node:assert/strict"
|
|
550
|
+
*
|
|
551
|
+
* assert.equal(
|
|
552
|
+
* // with `data-last`, a.k.a. `pipeable` API
|
|
553
|
+
* pipe(
|
|
554
|
+
* MutableHashSet.make(0, 1, 2),
|
|
555
|
+
* MutableHashSet.remove(0),
|
|
556
|
+
* MutableHashSet.has(0)
|
|
557
|
+
* ),
|
|
558
|
+
* false
|
|
559
|
+
* )
|
|
560
|
+
*
|
|
561
|
+
* assert.equal(
|
|
562
|
+
* // or piped with the pipe function
|
|
563
|
+
* MutableHashSet.make(0, 1, 2).pipe(
|
|
564
|
+
* MutableHashSet.remove(0),
|
|
565
|
+
* MutableHashSet.has(0)
|
|
566
|
+
* ),
|
|
567
|
+
* false
|
|
568
|
+
* )
|
|
569
|
+
*
|
|
570
|
+
* assert.equal(
|
|
571
|
+
* // or with `data-first` API
|
|
572
|
+
* MutableHashSet.remove(MutableHashSet.make(0, 1, 2), 0).pipe(
|
|
573
|
+
* MutableHashSet.has(0)
|
|
574
|
+
* ),
|
|
575
|
+
* false
|
|
576
|
+
* )
|
|
577
|
+
* ```
|
|
578
|
+
*
|
|
579
|
+
* @memberof MutableHashSet
|
|
121
580
|
* @since 2.0.0
|
|
122
581
|
* @category elements
|
|
582
|
+
* @see Other `MutableHashSet` elements are {@link module:MutableHashSet.add} {@link module:MutableHashSet.has} {@link module:MutableHashSet.size} {@link module:MutableHashSet.clear}
|
|
123
583
|
*/
|
|
124
584
|
export const remove: {
|
|
125
585
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
586
|
+
* `data-last` a.k.a. `pipeable` API
|
|
587
|
+
*
|
|
588
|
+
* ```ts
|
|
589
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
590
|
+
* import assert from "node:assert/strict"
|
|
591
|
+
*
|
|
592
|
+
* const set: MutableHashSet.MutableHashSet<number> = MutableHashSet.make(
|
|
593
|
+
* 0,
|
|
594
|
+
* 1,
|
|
595
|
+
* 2
|
|
596
|
+
* )
|
|
597
|
+
* const result: MutableHashSet.MutableHashSet<number> = pipe(
|
|
598
|
+
* set,
|
|
599
|
+
* MutableHashSet.remove(0)
|
|
600
|
+
* )
|
|
601
|
+
*
|
|
602
|
+
* assert(Object.is(set, result)) // set and result have the same identity
|
|
603
|
+
* assert.equal(pipe(result, MutableHashSet.has(0)), false) // it has correctly removed 0
|
|
604
|
+
* assert.equal(pipe(set, MutableHashSet.has(0)), false) // another proof that we are mutating the original MutableHashSet
|
|
605
|
+
* assert.equal(pipe(result, MutableHashSet.has(1)), true)
|
|
606
|
+
* assert.equal(pipe(result, MutableHashSet.has(2)), true)
|
|
607
|
+
* ```
|
|
608
|
+
*
|
|
609
|
+
* @template V - The type of the elements in the `MutableHashSet`.
|
|
610
|
+
* @param key - The key to be removed from the `MutableHashSet`.
|
|
611
|
+
* @returns A function that takes a `MutableHashSet` as input and returns the
|
|
612
|
+
* reference to the same `MutableHashSet` with the specified key removed.
|
|
128
613
|
*/
|
|
129
614
|
<V>(key: V): (self: MutableHashSet<V>) => MutableHashSet<V>
|
|
615
|
+
|
|
130
616
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
617
|
+
* `data-first` API
|
|
618
|
+
*
|
|
619
|
+
* ```ts
|
|
620
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
621
|
+
* import assert from "node:assert/strict"
|
|
622
|
+
*
|
|
623
|
+
* const set = MutableHashSet.make(0, 1, 2)
|
|
624
|
+
* const result = MutableHashSet.remove(set, 0)
|
|
625
|
+
*
|
|
626
|
+
* assert(Object.is(set, result)) // set and result have the same identity
|
|
627
|
+
* assert.equal(MutableHashSet.has(result, 0), false) // it has correctly removed 0
|
|
628
|
+
* assert.equal(MutableHashSet.has(set, 0), false) // it mutates the original MutableHashSet
|
|
629
|
+
* assert.equal(MutableHashSet.has(result, 1), true)
|
|
630
|
+
* assert.equal(MutableHashSet.has(result, 2), true)
|
|
631
|
+
* ```
|
|
632
|
+
*
|
|
633
|
+
* @template V - The type of the elements in the `MutableHashSet`.
|
|
634
|
+
* @param self - The `MutableHashSet` to which the key will be removed from.
|
|
635
|
+
* @param key - The value to be removed from the `MutableHashSet` if present.
|
|
636
|
+
* @returns The reference to the updated `MutableHashSet`.
|
|
133
637
|
*/
|
|
134
638
|
<V>(self: MutableHashSet<V>, key: V): MutableHashSet<V>
|
|
135
639
|
} = Dual.dual<
|
|
@@ -138,13 +642,65 @@ export const remove: {
|
|
|
138
642
|
>(2, (self, key) => (MutableHashMap.remove(self.keyMap, key), self))
|
|
139
643
|
|
|
140
644
|
/**
|
|
645
|
+
* Calculates the number of values in the `HashSet`.
|
|
646
|
+
*
|
|
647
|
+
* Time complexity: **`O(1)`**
|
|
648
|
+
*
|
|
649
|
+
* @memberof MutableHashSet
|
|
141
650
|
* @since 2.0.0
|
|
142
651
|
* @category elements
|
|
652
|
+
* @example
|
|
653
|
+
*
|
|
654
|
+
* ```ts
|
|
655
|
+
* import { MutableHashSet } from "effect"
|
|
656
|
+
* import assert from "node:assert/strict"
|
|
657
|
+
*
|
|
658
|
+
* assert.equal(MutableHashSet.size(MutableHashSet.empty()), 0)
|
|
659
|
+
*
|
|
660
|
+
* assert.equal(
|
|
661
|
+
* MutableHashSet.size(MutableHashSet.make(1, 2, 2, 3, 4, 3)),
|
|
662
|
+
* 4
|
|
663
|
+
* )
|
|
664
|
+
* ```
|
|
665
|
+
*
|
|
666
|
+
* @template V - The type of the elements to be stored in the `MutableHashSet`.
|
|
667
|
+
* @param self - The `MutableHashSet` instance for which the size is to be
|
|
668
|
+
* determined.
|
|
669
|
+
* @returns The total number of elements within the `MutableHashSet`.
|
|
670
|
+
* @see Other `MutableHashSet` elements are {@link module:MutableHashSet.add} {@link module:MutableHashSet.has} {@link module:MutableHashSet.remove} {@link module:MutableHashSet.clear}
|
|
143
671
|
*/
|
|
144
672
|
export const size = <V>(self: MutableHashSet<V>): number => MutableHashMap.size(self.keyMap)
|
|
145
673
|
|
|
146
674
|
/**
|
|
675
|
+
* Removes all values from the `MutableHashSet`.
|
|
676
|
+
*
|
|
677
|
+
* This function operates by delegating the clearing action to the underlying
|
|
678
|
+
* key map associated with the given `MutableHashSet`. It ensures that the hash
|
|
679
|
+
* set becomes empty while maintaining its existence and structure.
|
|
680
|
+
*
|
|
681
|
+
* @memberof MutableHashSet
|
|
147
682
|
* @since 2.0.0
|
|
148
683
|
* @category elements
|
|
684
|
+
* @example
|
|
685
|
+
*
|
|
686
|
+
* ```ts
|
|
687
|
+
* import { MutableHashSet, pipe } from "effect"
|
|
688
|
+
* import assert from "node:assert/strict"
|
|
689
|
+
*
|
|
690
|
+
* assert.deepStrictEqual(
|
|
691
|
+
* pipe(
|
|
692
|
+
* MutableHashSet.make(1, 2, 3, 4),
|
|
693
|
+
* MutableHashSet.clear,
|
|
694
|
+
* MutableHashSet.size
|
|
695
|
+
* ),
|
|
696
|
+
* 0
|
|
697
|
+
* )
|
|
698
|
+
* ```
|
|
699
|
+
*
|
|
700
|
+
* @param self - The `MutableHashSet` to clear.
|
|
701
|
+
* @returns The same `MutableHashSet` after all elements have been removed.
|
|
702
|
+
* @see Other `MutableHashSet` elements are {@link module:MutableHashSet.add} {@link module:MutableHashSet.has} {@link module:MutableHashSet.remove} {@link module:MutableHashSet.size}
|
|
149
703
|
*/
|
|
150
|
-
export const clear = <V>(self: MutableHashSet<V>): MutableHashSet<V> => (
|
|
704
|
+
export const clear = <V>(self: MutableHashSet<V>): MutableHashSet<V> => (
|
|
705
|
+
MutableHashMap.clear(self.keyMap), self
|
|
706
|
+
)
|