Skip to content

Instantly share code, notes, and snippets.

@ptsgrn
Created March 19, 2023 17:10
Show Gist options
  • Save ptsgrn/6c488958c65448f8d3f35c04efe61e04 to your computer and use it in GitHub Desktop.
Save ptsgrn/6c488958c65448f8d3f35c04efe61e04 to your computer and use it in GitHub Desktop.
Javascript implementation for Trie using RegEx
// This code is translated to JS from Python in https://stackoverflow.com/a/42789508/1202830 on StackOverflow.
// Answered by Eric Duminil <https://stackoverflow.com/users/6419007/eric-duminil> on March 14, 2017
// Edited by Just a learner <https://stackoverflow.com/users/170931/just-a-learner> on April 29, 2019
// Translated to JS by @ptsgrn <https://www.github.com/ptsgrn>
// Released under CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>
class Trie {
constructor() {
this.data = {};
}
add(word) {
let ref = this.data;
for (const char of word) {
ref[char] = char in ref ? ref[char] : {};
ref = ref[char];
}
ref[""] = 1;
}
dump() {
return this.data;
}
quote(char) {
return /[\\^$.*+?()[\]{}|]/.test(char) ? `\\${char}` : char;
}
_pattern(pData) {
const data = pData;
if ("" in data && Object.keys(data).length === 1) {
return "";
}
const alt = [];
const cc = [];
let q = 0;
for (const char of Object.keys(data).sort()) {
if (typeof data[char] === "object") {
try {
const recurse = this._pattern(data[char]);
alt.push(`${this.quote(char)}${recurse}`);
} catch (e) {
cc.push(this.quote(char));
}
} else {
q = 1;
}
}
const cconly = alt.length === 0;
if (cc.length > 0) {
if (cc.length === 1) {
alt.push(cc[0]);
} else {
alt.push(`[${cc.join("")}]`);
}
}
if (alt.length === 1) {
var result = alt[0];
} else {
result = `(?:${alt.join("|")})`;
}
if (q) {
if (cconly) {
result += "?";
} else {
result = `(?:${result})?`;
}
}
return result;
}
pattern() {
return this._pattern(this.dump());
}
}
const trie = new Trie();
trie.add("foo");
trie.add("bar");
trie.add("baz");
trie.add("qux");
trie.add("quux");
trie.add("quuz");
trie.add("corge");
trie.add("grault");
console.log("trie.dump():", JSON.stringify(trie.dump(), null, 2));
const pattern = new RegExp(trie.pattern());
console.log("pattern:", pattern);
console.log("pattern.test('foo'):", pattern.test("foo"));
console.log("pattern.test('bar'):", pattern.test("bar"));
console.log("pattern.test('baz'):", pattern.test("baz"));
console.log("pattern.test('unknown'):", pattern.test("unknown"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment