Skip to main content Link Search Menu Expand Document (external link)

MutableHashSet.ts overview

MutableHashSet

A mutable MutableHashSet provides a collection of unique values with efficient lookup, insertion and removal. Unlike its immutable sibling module:HashSet, a MutableHashSet can be modified in-place; operations like add, remove, and clear directly modify the original set rather than creating a new one. This mutability offers benefits like improved performance in scenarios where you need to build or modify a set incrementally.

What Problem Does It Solve?

MutableHashSet solves the problem of maintaining an unsorted collection where each value appears exactly once, with fast operations for checking membership and adding/removing values, in contexts where mutability is preferred for performance or implementation simplicity.

When to Use

Use MutableHashSet when you need:

  • A collection with no duplicate values
  • Efficient membership testing (O(1) average complexity)
  • In-place modifications for better performance
  • A set that will be built or modified incrementally
  • Local mutability in otherwise immutable code

Advanced Features

MutableHashSet provides operations for:

  • Adding and removing elements with direct mutation
  • Checking for element existence
  • Clearing all elements at once
  • Converting to/from other collection types

Performance Characteristics

  • Lookup operations (module:MutableHashSet.has): O(1) average time complexity
  • Insertion operations (module:MutableHashSet.add): O(1) average time complexity
  • Removal operations (module:MutableHashSet.remove): O(1) average time complexity
  • Iteration: O(n) where n is the size of the set

The MutableHashSet data structure implements the following traits:

  • Iterable: allows iterating over the values in the set
  • Pipeable: allows chaining operations with the pipe operator
  • Inspectable: allows inspecting the contents of the set

Operations Reference

Category Operation Description Complexity
constructors module:MutableHashSet.empty Creates an empty MutableHashSet O(1)
constructors module:MutableHashSet.fromIterable Creates a set from an iterable O(n)
constructors module:MutableHashSet.make Creates a set from multiple values O(n)
       
elements module:MutableHashSet.has Checks if a value exists in the set O(1) avg
elements module:MutableHashSet.add Adds a value to the set O(1) avg
elements module:MutableHashSet.remove Removes a value from the set O(1) avg
elements module:MutableHashSet.size Gets the number of elements O(1)
elements module:MutableHashSet.clear Removes all values from the set O(1)

Notes

Mutability Considerations:

Unlike most data structures in the Effect ecosystem, MutableHashSet is mutable. This means that operations like add, remove, and clear modify the original set rather than creating a new one. This can lead to more efficient code in some scenarios, but requires careful handling to avoid unexpected side effects.

When to Choose MutableHashSet vs module:HashSet:

  • Use MutableHashSet when you need to build or modify a set incrementally and performance is a priority
  • Use HashSet when you want immutability guarantees and functional programming patterns
  • Consider using module:HashSet’s bounded mutation context (via module:HashSet.beginMutation, module:HashSet.endMutation, and module:HashSet.mutate methods) when you need temporary mutability within an otherwise immutable context - this approach might be sufficient for many use cases without requiring a separate MutableHashSet
  • MutableHashSet is often useful for local operations where the mutability is contained and doesn’t leak into the broader application

Since v2.0.0


Exports Grouped by Category


constructors

empty

Creates an empty mutable hash set.

This function initializes and returns an empty MutableHashSet instance, which allows for efficient storage and manipulation of unique elements.

Time complexity: O(1)

Example

import { MutableHashSet } from "effect"

type T = unknown // replace with your type

// in places where the type can't be inferred, replace with your type
const set: MutableHashSet.MutableHashSet<T> = MutableHashSet.empty<T>()

See

  • Other MutableHashSet constructors are module:MutableHashSet.make module:MutableHashSet.fromIterable

Signature

declare const empty: <K = never>() => MutableHashSet<K>

Source

Since v2.0.0

fromIterable

Creates a new MutableHashSet from an iterable collection of values. Duplicate values are omitted.

Time complexity: O(n) where n is the number of elements in the iterable

Creating a MutableHashSet from an Array

import { MutableHashSet } from "effect"

const array: Iterable<number> = [1, 2, 3, 4, 5, 1, 2, 3] // Array<T> is also Iterable<T>
const mutableHashSet: MutableHashSet.MutableHashSet<number> = MutableHashSet.fromIterable(array)

console.log(
  // MutableHashSet.MutableHashSet<T> is also an Iterable<T>
  Array.from(mutableHashSet)
) // Output: [1, 2, 3, 4, 5]

Creating a MutableHashSet from a Set

import { MutableHashSet, pipe } from "effect"

console.log(
  pipe(
    // Set<string> is an Iterable<string>
    new Set(["apple", "banana", "orange", "apple"]),
    // constructs MutableHashSet from an Iterable Set
    MutableHashSet.fromIterable,
    // since MutableHashSet it is itself an Iterable, we can pass it to other functions expecting an Iterable
    Array.from
  )
) // Output: ["apple", "banana", "orange"]

Creating a MutableHashSet from a Generator

import { MutableHashSet } from "effect"

// Generator functions return iterables
function* fibonacci(n: number): Generator<number, void, never> {
  let [a, b] = [0, 1]
  for (let i = 0; i < n; i++) {
    yield a
    ;[a, b] = [b, a + b]
  }
}

// Create a MutableHashSet from the first 10 Fibonacci numbers
const fibonacciSet = MutableHashSet.fromIterable(fibonacci(10))

console.log(Array.from(fibonacciSet))
// Outputs: [0, 1, 2, 3, 5, 8, 13, 21, 34] but in unsorted order

Creating a MutableHashSet from another module:MutableHashSet

import { MutableHashSet, pipe } from "effect"

console.log(pipe(MutableHashSet.make(1, 2, 3, 4), MutableHashSet.fromIterable, Array.from)) // Output: [1, 2, 3, 4]

Creating a MutableHashSet from an module:HashSet

import { HashSet, MutableHashSet, pipe } from "effect"

console.log(
  pipe(
    HashSet.make(1, 2, 3, 4), // it works also with its immutable HashSet sibling
    MutableHashSet.fromIterable,
    Array.from
  )
) // Output: [1, 2, 3, 4]

Creating a MutableHashSet from other Effect’s data structures like Chunk

import { Chunk, MutableHashSet, pipe } from "effect"

console.log(
  pipe(
    Chunk.make(1, 2, 3, 4), //  Chunk is also an Iterable<T>
    MutableHashSet.fromIterable,
    Array.from
  )
) // Outputs: [1, 2, 3, 4]

See

  • Other MutableHashSet constructors are module:MutableHashSet.empty module:MutableHashSet.make

Signature

declare const fromIterable: <K = never>(keys: Iterable<K>) => MutableHashSet<K>

Source

Since v2.0.0

make

Construct a new MutableHashSet from a variable number of values.

Time complexity: O(n) where n is the number of elements

Example

import { Equal, Hash, MutableHashSet } from "effect"
import assert from "node:assert/strict"

class Character implements Equal.Equal {
  readonly name: string
  readonly trait: string

  constructor(name: string, trait: string) {
    this.name = name
    this.trait = trait
  }

  // Define equality based on name, and trait
  [Equal.symbol](that: Equal.Equal): boolean {
    if (that instanceof Character) {
      return Equal.equals(this.name, that.name) && Equal.equals(this.trait, that.trait)
    }
    return false
  }

  // Generate a hash code based on the sum of the character's name and trait
  [Hash.symbol](): number {
    return Hash.hash(this.name + this.trait)
  }

  static readonly of = (name: string, trait: string): Character => {
    return new Character(name, trait)
  }
}

const mutableCharacterHashSet = MutableHashSet.make(
  Character.of("Alice", "Curious"),
  Character.of("Alice", "Curious"),
  Character.of("White Rabbit", "Always late"),
  Character.of("Mad Hatter", "Tea enthusiast")
)

assert.equal(MutableHashSet.has(mutableCharacterHashSet, Character.of("Alice", "Curious")), true)
assert.equal(MutableHashSet.has(mutableCharacterHashSet, Character.of("Fluffy", "Kind")), false)

See

  • Other MutableHashSet constructors are module:MutableHashSet.fromIterable module:MutableHashSet.empty

Signature

declare const make: <Keys extends ReadonlyArray<unknown>>(...keys: Keys) => MutableHashSet<Keys[number]>

Source

Since v2.0.0

elements

add

Checks whether the MutableHashSet contains the given element, and adds it if not.

Time complexity: O(1) average

Syntax

import { MutableHashSet, pipe } from "effect"

// with data-last, a.k.a. pipeable API
pipe(MutableHashSet.empty(), MutableHashSet.add(0), MutableHashSet.add(0))

// or piped with the pipe function
MutableHashSet.empty().pipe(MutableHashSet.add(0))

// or with data-first API
MutableHashSet.add(MutableHashSet.empty(), 0)

See

  • Other MutableHashSet elements are module:MutableHashSet.remove module:MutableHashSet.size module:MutableHashSet.clear module:MutableHashSet.has

Signature

declare const add: {
  <V>(key: V): (self: MutableHashSet<V>) => MutableHashSet<V>
  <V>(self: MutableHashSet<V>, key: V): MutableHashSet<V>
}

Source

Since v2.0.0

clear

Removes all values from the MutableHashSet.

This function operates by delegating the clearing action to the underlying key map associated with the given MutableHashSet. It ensures that the hash set becomes empty while maintaining its existence and structure.

Example

import { MutableHashSet, pipe } from "effect"
import assert from "node:assert/strict"

assert.deepStrictEqual(pipe(MutableHashSet.make(1, 2, 3, 4), MutableHashSet.clear, MutableHashSet.size), 0)

See

  • Other MutableHashSet elements are module:MutableHashSet.add module:MutableHashSet.has module:MutableHashSet.remove module:MutableHashSet.size

Signature

declare const clear: <V>(self: MutableHashSet<V>) => MutableHashSet<V>

Source

Since v2.0.0

has

Checks if the specified value exists in the MutableHashSet.

Time complexity: O(1) average

Syntax

import { MutableHashSet, pipe } from "effect"
import assert from "node:assert/strict"

assert.equal(
  // with `data-last`, a.k.a. `pipeable` API
  pipe(MutableHashSet.make(0, 1, 2), MutableHashSet.has(3)),
  false
)

assert.equal(
  // or piped with the pipe function
  MutableHashSet.make(0, 1, 2).pipe(MutableHashSet.has(3)),
  false
)

assert.equal(
  // or with `data-first` API
  MutableHashSet.has(MutableHashSet.make(0, 1, 2), 3),
  false
)

See

  • Other MutableHashSet elements are module:MutableHashSet.add module:MutableHashSet.remove module:MutableHashSet.size module:MutableHashSet.clear

Signature

declare const has: { <V>(key: V): (self: MutableHashSet<V>) => boolean; <V>(self: MutableHashSet<V>, key: V): boolean }

Source

Since v2.0.0

remove

Removes a value from the MutableHashSet.

Time complexity: O(1) average

Syntax

import { MutableHashSet, pipe } from "effect"
import assert from "node:assert/strict"

assert.equal(
  // with `data-last`, a.k.a. `pipeable` API
  pipe(MutableHashSet.make(0, 1, 2), MutableHashSet.remove(0), MutableHashSet.has(0)),
  false
)

assert.equal(
  // or piped with the pipe function
  MutableHashSet.make(0, 1, 2).pipe(MutableHashSet.remove(0), MutableHashSet.has(0)),
  false
)

assert.equal(
  // or with `data-first` API
  MutableHashSet.remove(MutableHashSet.make(0, 1, 2), 0).pipe(MutableHashSet.has(0)),
  false
)

See

  • Other MutableHashSet elements are module:MutableHashSet.add module:MutableHashSet.has module:MutableHashSet.size module:MutableHashSet.clear

Signature

declare const remove: {
  <V>(key: V): (self: MutableHashSet<V>) => MutableHashSet<V>
  <V>(self: MutableHashSet<V>, key: V): MutableHashSet<V>
}

Source

Since v2.0.0

size

Calculates the number of values in the HashSet.

Time complexity: O(1)

Example

import { MutableHashSet } from "effect"
import assert from "node:assert/strict"

assert.equal(MutableHashSet.size(MutableHashSet.empty()), 0)

assert.equal(MutableHashSet.size(MutableHashSet.make(1, 2, 2, 3, 4, 3)), 4)

See

  • Other MutableHashSet elements are module:MutableHashSet.add module:MutableHashSet.has module:MutableHashSet.remove module:MutableHashSet.clear

Signature

declare const size: <V>(self: MutableHashSet<V>) => number

Source

Since v2.0.0

models

MutableHashSet (interface)

Signature

export interface MutableHashSet<out V> extends Iterable<V>, Pipeable, Inspectable {
  readonly [TypeId]: TypeId

  /** @internal */
  readonly keyMap: MutableHashMap.MutableHashMap<V, boolean>
}

Source

Since v2.0.0

symbol

TypeId (type alias)

Signature

type TypeId = typeof TypeId

Source

Since v2.0.0