// ets_tracing: off /* adapted from https://github.com/gcanti/fp-ts */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import * as Op from "../../../Option/index.js" import { fromNullable } from "../../../Option/index.js" import type { MutableMap } from "../../../Support/Mutable/index.js" import * as Tp from "../Tuple/index.js" /** * Map type */ export type Map = ReadonlyMap /** * Create from a key-value array */ export function make( values: Iterable> ): Map { const map = new Map() for (const _ of values) { if (Tp.isTuple(_)) { map.set(_.get(0), _.get(1)) } else { map.set(_[0], _[1]) } } return map } /** * Removes None values */ export function compact(fa: Map>): Map { const m = new Map() const entries = fa.entries() let e: Next]> while (!(e = entries.next()).done) { const [k, oa] = e.value if (Op.isSome(oa)) { m.set(k, oa.value) } } return m } /** * Empty Map */ export const empty: Map = new Map() /** * Filter out None and map */ export function filterMap_( fa: Map, f: (a: A) => Op.Option ): Map { return filterMapWithIndex_(fa, (_, a) => f(a)) } /** * Filter out None and map */ export function filterMap(f: (a: A) => Op.Option) { return (fa: Map) => filterMap_(fa, f) } /** * Filter out None and map */ export function filterMapWithIndex_( fa: Map, f: (k: K, a: A) => Op.Option ): Map { const m = new Map() const entries = fa.entries() let e: Next // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, a] = e.value const o = f(k, a) if (Op.isSome(o)) { m.set(k, o.value) } } return m } /** * Filter out None and map */ export function filterMapWithIndex(f: (k: K, a: A) => Op.Option) { return (fa: Map) => filterMapWithIndex_(fa, f) } /** * Filter out None and map */ export function filterWithIndex_( fa: Map, p: (k: K, a: A) => boolean ): Map { const m = new Map() const entries = fa.entries() let e: Next // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, a] = e.value if (p(k, a)) { m.set(k, a) } } return m } /** * Filter out None and map */ export function filterWithIndex(p: (k: K, a: A) => boolean) { return (fa: Map) => filterWithIndex_(fa, p) } /** * Construct a new Readonly Map */ export function fromMutable(m: MutableMap): Map { return new Map(m) } /** * Test whether or not a map is empty */ export function isEmpty(d: Map): boolean { return d.size === 0 } /** * Maps values using f */ export function map_(fa: Map, f: (a: A) => B): Map { return mapWithIndex_(fa, (_, a) => f(a)) } /** * Maps values using f */ export function map(f: (a: A) => B) { return (fa: Map) => map_(fa, f) } /** * Maps values using f */ export function mapWithIndex_(fa: Map, f: (k: K, a: A) => B): Map { const m = new Map() const entries = fa.entries() let e: Next while (!(e = entries.next()).done) { const [key, a] = e.value m.set(key, f(key, a)) } return m } /** * Maps values using f */ export function mapWithIndex(f: (k: K, a: A) => B) { return (fa: Map) => mapWithIndex_(fa, f) } export interface Next { readonly done?: boolean readonly value: A } /** * Create a map with one key/value pair */ export function singleton(k: K, a: A): Map { return new Map([[k, a]]) } /** * Calculate the number of key/value pairs in a map */ export function size(d: Map): number { return d.size } /** * Construct a new mutable map by copying this one */ export function toMutable(m: Map): MutableMap { return new Map(m) } export function insert_(self: ReadonlyMap, k: K, v: V): ReadonlyMap { const m = copy(self) m.set(k, v) return m } export function insert(k: K, v: V) { return (self: ReadonlyMap) => insert_(self, k, v) } export function remove_(self: ReadonlyMap, k: K): ReadonlyMap { const m = copy(self) m.delete(k) return m } export function remove(k: K) { return (self: ReadonlyMap) => remove_(self, k) } export function removeMany_( self: ReadonlyMap, ks: Iterable ): ReadonlyMap { const m = copy(self) for (const k of ks) { m.delete(k) } return m } export function removeMany(ks: Iterable) { return (self: ReadonlyMap) => removeMany_(self, ks) } export function lookup_(m: ReadonlyMap, k: K): Op.Option> { return fromNullable(m.get(k)) } export function lookup(k: K) { return (m: ReadonlyMap) => lookup_(m, k) } export function copy(self: ReadonlyMap) { const m = new Map() self.forEach((v, k) => { m.set(k, v) }) return m }