Skip to content

Commit

Permalink
fix: xmap
Browse files Browse the repository at this point in the history
  • Loading branch information
izatop committed May 28, 2022
1 parent c4806b4 commit c9c177e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@commitlint/cli": "^17.0.1",
"@commitlint/config-conventional": "^17.0.0",
"@types/jest": "^27.5.1",
"@types/node": "^17.0.35",
"@types/node": "^17.0.36",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
"cross-env": "^7.0.3",
Expand Down
39 changes: 37 additions & 2 deletions packages/util/src/Map/XMap.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
import {assert} from "../assert";
import {isFunction} from "../is";
import {isArray, isFunction} from "../is";

export type XMapArrayFactory<K, V> = (value: V, index: number, array: V[]) => K;
export type XMapInitializer<K, V> = (key: K) => V;
export type XMapArgs<K, V> = |
[values: [K, V][], initializer?: (key: K) => V] |
[initializer?: (key: K) => V];

export class XMap<K, V> extends Map<K, V> {
readonly #initializer?: XMapInitializer<K, V>;

constructor(initializer?: (key: K) => V) {
constructor(...args: XMapArgs<K, V>) {
super();
const [valuesOr, initializer] = args;
this.#initializer = initializer;

if (isArray(valuesOr)) {
valuesOr.forEach(([key, value]) => this.set(key, value));
this.#initializer = initializer;
}

if (isFunction(valuesOr)) {
this.#initializer = valuesOr;
}
}

public static fromArray<K, V>(values: V[],
key: XMapArrayFactory<K, V>,
initializer?: XMapInitializer<K, V>): XMap<K, V> {
return new XMap(
values.map((value, index, array) => [key(value, index, array), value]),
initializer,
);
}

public static fromObject<T extends Record<any, any>, K extends keyof T>(values: T,
initializer?: XMapInitializer<K, T[K]>): XMap<K, T[K]> {
return new XMap<K, T[K]>(Object.entries(values) as [K, T[K]][], initializer);
}

public ensure(key: K, initializer: XMapInitializer<K, V> | undefined = this.#initializer): V {
Expand All @@ -24,4 +52,11 @@ export class XMap<K, V> extends Map<K, V> {

return this.get(key) as V;
}

public pick(key: K): V | undefined {
const value = this.get(key);
this.delete(key);

return value;
}
}
18 changes: 18 additions & 0 deletions packages/util/test/src/map/XMap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,22 @@ describe("XMap", () => {
expect(() => map.ensure(2, () => false)).not.toThrowError();
expect(() => map.ensure(3, () => null)).not.toThrowError();
});

test("pick", () => {
const map = new XMap<number, number>();
map.set(1, 2);
map.set(2, 3);
expect(map.pick(1)).toBe(2);
expect([...map.entries()]).toEqual([[2, 3]]);
});

test("fromArray", () => {
const map = XMap.fromArray([1, 2, 3], (_, index) => index);
expect([...map.entries()]).toEqual([[0, 1], [1, 2], [2, 3]]);
});

test("fromObject", () => {
const map = XMap.fromObject({foo: 1, bar: 2});
expect([...map.entries()]).toEqual([["foo", 1], ["bar", 2]]);
});
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2005,10 +2005,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==

"@types/node@^17.0.35":
version "17.0.35"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.35.tgz#635b7586086d51fb40de0a2ec9d1014a5283ba4a"
integrity sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==
"@types/node@^17.0.36":
version "17.0.36"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.36.tgz#c0d5f2fe76b47b63e0e0efc3d2049a9970d68794"
integrity sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==

"@types/normalize-package-data@^2.4.0":
version "2.4.1"
Expand Down

0 comments on commit c9c177e

Please sign in to comment.