Files
redux-scraper/app/javascript/bundles/Main/lib/Trie.ts
2024-12-22 19:10:33 +00:00

92 lines
2.3 KiB
TypeScript

interface SerializedTrie<T> {
// terminal node?
t: 1 | 0;
// value of the node
v: T;
// optional children
c?: { [s: string]: SerializedTrie<T> };
}
export class TrieNode<T> {
public terminal: boolean;
public value: T;
public children: Map<string, TrieNode<T>>;
public serialized: SerializedTrie<T>;
constructor(ser: SerializedTrie<T>) {
this.terminal = ser.t == 1;
this.value = ser.v;
this.children = new Map();
this.serialized = ser;
if (ser.c != null) {
for (const [key, value] of Object.entries(ser.c)) {
this.children.set(key, new TrieNode(value));
}
}
}
}
export default class Trie<T> {
public root: TrieNode<T>;
constructor(ser: SerializedTrie<T>) {
this.root = new TrieNode(ser);
}
public nodeForPrefix(key: string): {
chain: string[];
node: TrieNode<T> | null;
} {
let chain = [];
let node = this.root;
let remaining = key;
while (node && remaining.length > 0) {
let exactChild = null;
console.log('remaining: ', remaining);
for (const [childKey, child] of node.children.entries()) {
if (remaining.startsWith(childKey)) {
console.log('exact match for: ', childKey);
exactChild = child;
chain.push(childKey);
remaining = remaining.slice(childKey.length);
break;
}
}
// if an exact match was found, continue iterating
if (exactChild) {
node = exactChild;
continue;
}
console.log('looking for partial match for ', remaining);
for (const [childKey, child] of node.children.entries()) {
const startsWith = childKey.startsWith(remaining);
console.log(
'test ',
childKey,
' against ',
remaining,
': ',
startsWith,
' ',
child.serialized,
);
if (startsWith) {
console.log('partial match for: ', remaining, ': ', child.serialized);
chain.push(childKey);
return { chain, node: child };
}
}
console.log('did not find partial, bailing!');
return { chain, node: null };
}
// // return remaining.length === 0 && node && node.terminal ? node : null;
console.log('returning child ', node, ' for remaining ', remaining);
return { chain, node };
}
}