Sorry for the collapsed name, I tried my best to make it conscious. Well, if you have an idea, change it!
Not to be confused, this is Emacs Lisp loop , not Common Lisp:
(defun hxswfml-build-trie (alist) "Builds a trie (a list, containing number of hash-maps, each hash-map uses single character for a key, except for `t' symbol, which, if present as a key is the key for the value one has to substitute with." (loop for (key . value) in alist with trie = (make-hash-table) do (loop for c across key with branch = (or (gethash c trie) (puthash c (make-hash-table) trie)) with first-time = t do (if first-time (setq first-time nil) (setq branch (or (gethash c branch) (puthash c (make-hash-table) branch)))) finally (puthash t value branch)) finally (return trie)))
This converts alist to a tree of hash tables, where each table contains keys, which are the characters of the rows that I later searched and replaced. This is necessary to optimize the search for several keys with, possibly, a similar prefix in most of the text, and then replace each of them with the corresponding key.
The problem is that in the inner loop, I would like to initialize branch to trie , and then in all subsequent iterations set it to a new hash table (created for a character that is not part of the known prefix) or a hash table that has already been created for the character from the prefix.
Ideally, it looks something like this:
for branch = (or (and branch (gethash c branch)) (puthash c (make-hash-table) trie)) ;; ^-----------------^------- cannot reference it here
And that is why I have a stupid first-time flag that I could avoid. Can I somehow use the form initially or perhaps rebuild function in any other way to avoid this flag and further if it? Itโs not very important that this function is fast (the search should be fast, but you donโt need to build a tree), but it looks just ugly :)
user797257
source share