Created
March 19, 2023 17:10
-
-
Save ptsgrn/6c488958c65448f8d3f35c04efe61e04 to your computer and use it in GitHub Desktop.
Javascript implementation for Trie using RegEx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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