I keep getting empty maps when i am passing data into two hash maps in clojure, i know that the data is being sent through the functions as i have used print statements that show it correct data, its just when i assoc the data to the map it doesnt appear to do anything and leaves me with {}
Can anyone see what i am doing wrong??
(defn sort-string [y]
(apply str (sort y)))
(defn get-unique [y]
(let [x (sort-string (str/lower-case y))
hashmap1 (hash-map)
hashmap2 (hash-map)]
(if-not (contains? hashmap1 x)
(assoc hashmap1 x, y)
(assoc hashmap2 y, y))
(if-not (get hashmap1 x) y)
(dissoc hashmap2 (get hashmap1 x))))
(for [strings '("door" " rood" "pen" "open" "high" "low" "wall" "lawl" "#")]
(get-unique strings))
Clojure maps are immutable. So the assoc
s, which return modified maps, have no effect, as the returned values are not used.
I don't know what you're trying to do, but the following might get you on the right lines:
(defn get-unique [y]
(let [x (sort-string (str/lower-case y))
hashmap1 (hash-map)
hashmap2 (hash-map)
[hashmap1 hashmap2] (if-not (contains? hashmap1 x)
[(assoc hashmap1 x, y) (assoc hashmap2 y, y)]
[hashmap1 hashmap2])]
(if-not (= (get hashmap1 x) y)
(dissoc hashmap2 (get hashmap1 x))
hashmap2)))
For example,
(for [strings '("door" " rood" "pen" "open" "high" "low" "wall" "lawl" "#")]
(get-unique strings))
;({"door" "door"} {" rood" " rood"} {"pen" "pen"} {"open" "open"} {"high" "high"} {"low" "low"} {"wall" "wall"} {"lawl" "lawl"} {"#" "#"})
Now that your comment tells me you are trying to group anagrams together, using sort-string
to test for equivalences ...
You can do this using group-by
. For example,
(let [strings '("door" " rood" "pen" "open" "high" "low" "wall" "lawl" "#")]
(group-by sort-string strings))
... produces ...
{"door" ["door" "rood"], "enp" ["pen"], "enop" ["open"], "ghhi" ["high"], "low" ["low"], "allw" ["wall" "lawl"], "#" ["#"]}
I think the mistake you're making is assuming hashmap1
and hashmap2
are mutable. assoc
returns a new hashmap with the associated key and value, but the original remains unchanged.
You can see this in a repl like so:
user=> (def my-map {:a 1 :b 2})
#'user/my-map
user=> my-map
{:a 1, :b 2}
user=> (assoc my-map :c 3)
{:a 1, :b 2, :c 3}
user=> my-map
{:a 1, :b 2}
This means your block:
(if-not (contains? hashmap1 x)
(assoc hashmap1 x, y)
(assoc hashmap2 y, y))
just created a new hashmap with x as a key and y as a value and threw didn't do anything with it.
Maybe you could write another function to create the new map and return it like so:
(defn add-if-not-contains [m1 m2 x y]
(if-not (contains? m1 x)
[(assoc m1 x y) m2]
[m1 (assoc m2 y y)]))
But your solution is still overly complicated I think. I'm guessing you want a single sorted element that does not have any other permutations in the list.
user=> (def my-strings ["door" " rood" "pen" "open" "high" "low" "wall" "lawl" "#"])
#'user/my-string
user=> (distinct (map sort-string my-strings))
("door" " door" "enp" "enop" "ghhi" "low" "allw" "#")
If you want to just get words that have no permutation, you might try something like this
(frequencies (map sort-string ["door" "rood" "odor" "pen"]))
{"door" 3, "enp" 1}
Filtering that result to find entries with a value of 1 and finding the original word from the permutation are left as an exercise.