Clojure中的空地图

时间:2016-01-31 17:24:11

标签: clojure hashmap

当我将数据传递到clojure中的两个哈希映射时,我一直得到空映射,我知道数据是通过函数发送的,因为我使用了显示正确数据的print语句,就在我关联数据时到地图它似乎没有做任何事情,留给我{}

谁能看到我做错了什么?

(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))

2 个答案:

答案 0 :(得分:0)

Clojure地图是不可变的。因此,返回修改后的地图的assoc s无效,因为未使用返回值。

我不知道你要做什么,但以下内容可能会让你走上正确的路线:

(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 [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"} {"#" "#"})

现在您的评论告诉我您正在尝试将字谜组合在一起,使用sort-string来测试等效性...

您可以使用group-by执行此操作。例如,

(let [strings '("door" " rood" "pen" "open" "high" "low" "wall" "lawl" "#")]
  (group-by sort-string strings))

...生产......

{"door" ["door" "rood"], "enp" ["pen"], "enop" ["open"], "ghhi" ["high"], "low" ["low"], "allw" ["wall" "lawl"], "#" ["#"]}

答案 1 :(得分:0)

我认为您犯的错误是假设hashmap1hashmap2是可变的。 assoc返回一个带有关联键和值的新hashmap,但原始值保持不变。

你可以在这样的repl中看到这个:

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}

这意味着您的阻止:

(if-not (contains? hashmap1 x)
  (assoc hashmap1 x, y)
  (assoc hashmap2 y, y))

刚刚创建了一个新的hashmap,其中x为键,y为值,并且没有对它做任何事情。

也许您可以编写另一个函数来创建新地图并将其返回:

(defn add-if-not-contains [m1 m2 x y]
    (if-not (contains? m1 x)
        [(assoc m1 x y) m2]
        [m1 (assoc m2 y y)]))

但我认为你的解决方案仍然过于复杂。我猜你想要一个在列表中没有任何其他排列的单个排序元素。

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" "#")

如果你想获得没有排列的单词,你可以尝试这样的东西

(frequencies (map sort-string ["door" "rood" "odor" "pen"]))
{"door" 3, "enp" 1}

过滤该结果以查找值为1的条目并从排列中查找原始单词将留作练习。