diff options
| author | (quasar) nebula <qznebula@protonmail.com> | 2026-04-02 23:27:55 -0300 |
|---|---|---|
| committer | (quasar) nebula <qznebula@protonmail.com> | 2026-04-02 23:27:55 -0300 |
| commit | 818e89c7ee0a426ac5f66a4079c70e047627a7f2 (patch) | |
| tree | 489d6651767e7b7214324e8dfbc47fed1d2deda6 /src/common-util | |
| parent | b250e91a74b244cc5decd79f5604cfb8a811421a (diff) | |
content: generateDividedTrackList: context groups
Diffstat (limited to 'src/common-util')
| -rw-r--r-- | src/common-util/sugar.js | 32 | ||||
| -rw-r--r-- | src/common-util/wiki-data.js | 51 |
2 files changed, 80 insertions, 3 deletions
diff --git a/src/common-util/sugar.js b/src/common-util/sugar.js index c988156c..26f33c20 100644 --- a/src/common-util/sugar.js +++ b/src/common-util/sugar.js @@ -229,6 +229,38 @@ export const mapInPlace = (array, fn) => export const unique = (arr) => Array.from(new Set(arr)); +export function* permutations(array) { + switch (array.length) { + case 0: return; + case 1: yield array; return; + default: { + const behind = []; + const ahead = array.slice(); + while (ahead.length) { + const here = ahead.shift(); + + yield* + permutations([...behind, ...ahead]) + .map(slice => [here, ...slice]); + + behind.push(here); + } + } + } +} + +export function* runs(array) { + switch (array.length) { + case 0: return; + case 1: yield array; return; + default: { + yield* runs(array.slice(1)).map(run => [array[0], ...run]); + yield [array[0]]; + yield* runs(array.slice(1)); + } + } +} + export const compareArrays = (arr1, arr2, {checkOrder = true} = {}) => arr1.length === arr2.length && (checkOrder diff --git a/src/common-util/wiki-data.js b/src/common-util/wiki-data.js index 74222e9e..21e15725 100644 --- a/src/common-util/wiki-data.js +++ b/src/common-util/wiki-data.js @@ -506,8 +506,23 @@ export class TupleMap { } export class TupleMapForBabies { - #here = new WeakMap(); - #next = new WeakMap(); + #here; + #next; + #mode; + + constructor(mode = 'weak') { + if (mode === 'weak') { + this.#mode = 'weak'; + this.#here = new WeakMap(); + this.#next = new WeakMap(); + } else if (mode === 'strong') { + this.#mode = 'strong'; + this.#here = new Map(); + this.#next = new Map(); + } else { + throw new Error(`Expected mode to be weak or strong`); + } + } set(...args) { const first = args.at(0); @@ -519,7 +534,7 @@ export class TupleMapForBabies { } else if (this.#next.has(first)) { this.#next.get(first).set(...rest, last); } else { - const tupleMap = new TupleMapForBabies(); + const tupleMap = new TupleMapForBabies(this.#mode); this.#next.set(first, tupleMap); tupleMap.set(...rest, last); } @@ -550,6 +565,36 @@ export class TupleMapForBabies { return false; } } + + *keys() { + if (this.#mode === 'weak') { + throw new Error(`Can't get keys of a weak tuple map`); + } + + for (const key of this.#here.keys()) { + yield [key]; + + if (this.#next.has(key)) { + for (const next of this.#next.get(key).keys()) { + yield [key, ...next]; + } + } + } + } + + *values() { + if (this.#mode === 'weak') { + throw new Error(`Can't get values of a weak tuple map`); + } + + for (const key of this.#here.keys()) { + yield this.#here.get(key); + + if (this.#next.has(key)) { + yield* this.#next.get(key).values(); + } + } + } } const combinedWikiDataTupleMap = new TupleMapForBabies(); |