I want to create a function that holds the frequencies of strings I deem as spam. I'm trying to use an atomic map that can be updated as I give the map a new string.
Desired Behavior
user> (train-word spam "FREE")
{"FREE": 1}
user> (train-word spam "FREE")
{"FREE" : 2}
user> (train-word spam "MONEY")
{"FREE" : 2 "MONEY" : 1}
So far I have tried
(def spam (atom {}))
(defn train-word [m word]
(swap! update-in m [word]
(fn [old] (inc (or old 0)))))
but that produces an error:
clojure.lang.Atom cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:702)
I'm new to Clojure so I did a quick prototype in Python
from collections import defaultdict
spam = defaultdict(int)
def train_word(word, spam):
spam[word] += 1
What is the idiomatic way to manage state using an atom to update current values as well as add new ones? Thanks!
Just need to pass the atom before the function in the call to swap!
.
user> (def spam (atom {}))
#'user/spam
user> (defn train-word [m word]
(swap! m update-in [word]
(fn [old] (inc (or old 0)))))
#'user/train-word
user> (train-word spam "FREE")
{"FREE" 1}
swap!
constructs the function call by:
(update-in [word] (fn [old] (inc (or old 0)))
@m
(update-in @m [word] (fn [old] (inc (or old 0)))
{"FREE" 1}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With