mirror of
https://github.com/shoedler/crossbow.git
synced 2026-07-22 07:40:26 +00:00
Fix contrast yet again, cleanup
This commit is contained in:
parent
541d93ac64
commit
2c3e4aa5bc
3 changed files with 2 additions and 112 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "crossbow",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "crossbow",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"license": "gplv3",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.1",
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
// Copyright (C) 2023 - shoedler - github.com/shoedler
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
export type Trie<T> = {
|
||||
value?: T;
|
||||
next: { [key: string]: Trie<T> };
|
||||
};
|
||||
|
||||
const createTrie = <T>(items: T[], keySelector: (item: T) => string): Trie<T> => {
|
||||
const root: Trie<T> = { next: {} };
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
addOrUpdate(root, item, keySelector, (o, n) => {
|
||||
throw new Error(`Duplicate entry: ${JSON.stringify(n)}`);
|
||||
});
|
||||
}
|
||||
|
||||
return root;
|
||||
};
|
||||
|
||||
const addOrUpdate = <T>(
|
||||
root: Trie<T>,
|
||||
item: T,
|
||||
keySelector: (item: T) => string,
|
||||
update: (oldItem: T, newItem: T) => T
|
||||
): void => {
|
||||
const key = keySelector(item).toLocaleLowerCase();
|
||||
|
||||
let trie = root;
|
||||
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
const c = key[i];
|
||||
|
||||
trie.next[c] = trie.next[c] || { next: {} };
|
||||
|
||||
if (i === key.length - 1) {
|
||||
if (trie.next[c].value) {
|
||||
trie.next[c].value = update(trie.next[c].value as T, item);
|
||||
} else {
|
||||
trie.next[c].value = item;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
trie = trie.next[c] as Trie<T>;
|
||||
}
|
||||
};
|
||||
|
||||
const tryGet = <T>(root: Trie<T>, key: string): T | undefined => {
|
||||
let trie = root;
|
||||
let i = 0;
|
||||
|
||||
while (i < key.length && trie) {
|
||||
trie = trie.next[key[i++]] as Trie<T>;
|
||||
}
|
||||
|
||||
return trie.value as T | undefined;
|
||||
};
|
||||
|
||||
const toArray = <T>(root: Trie<T>): T[] => {
|
||||
const result: T[] = [];
|
||||
|
||||
for (const value of traverse(root)) {
|
||||
result.push(value);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const length = <T>(root: Trie<T>): number => {
|
||||
let result = 0;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const _ of traverse(root)) {
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
function* traverse<T>(trie: Trie<T>): Generator<T> {
|
||||
if (trie.value) {
|
||||
yield trie.value;
|
||||
}
|
||||
|
||||
for (const key in trie.next) {
|
||||
yield* traverse(trie.next[key]);
|
||||
}
|
||||
}
|
||||
|
||||
export const TrieTools = {
|
||||
createTrie,
|
||||
addOrUpdate,
|
||||
tryGet,
|
||||
toArray,
|
||||
length,
|
||||
traverse,
|
||||
};
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
margin-left: 0.2rem;
|
||||
font-size: var(--font-smallest);
|
||||
color: var(--text-muted);
|
||||
opacity: var(--icon-opacity);
|
||||
padding: 0.2rem;
|
||||
padding-top: 0rem;
|
||||
padding-bottom: 0.1rem;
|
||||
|
|
|
|||
Loading…
Reference in a new issue