【问题标题】:Empty Maps in ClojureClojure 中的空映射
【发布时间】:2016-01-31 17:24:11
【问题描述】:

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

谁能看到我做错了什么??

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

【问题讨论】:

  • 你期望的输出是什么?
  • 小问题:(hash-map) 是一种非常规的写法{}contains? check 永远不会返回 true,因为它正在检查的哈希映射 100% 保证为空案例。
  • 根据您对my answer 的评论,您正在尝试将字谜组合在一起,使用sort-string 生成对所有字谜都相同的东西,仅此而已。 请将此纳入您的问题。

标签: clojure hashmap


【解决方案1】:

Clojure 映射是不可变的。因此,return 修改映射的assocs 无效,因为未使用返回的值。

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

(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"], "#" ["#"]}

【讨论】:

  • 有没有办法将 X 作为键和 Y 作为值添加到我的地图??
  • @ElliottSmelliott 使用来自assoc 的返回值,如上所述和@Munk 的答案。
  • 这就是我需要的,但我只想返回唯一的字符串,所以在“门”“路德”气味“笔”外只返回笔,因为其他三个可以组成另一个单词 rood = door + odor 但笔是独一无二的,因为没有其他词可以匹配 pen
【解决方案2】:

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

你可以在这样的 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))

刚刚创建了一个以 x 作为键和 y 作为值的新哈希图,并且 throw 对它没有做任何事情。

也许您可以编写另一个函数来创建新地图并像这样返回它:

(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 的条目并从排列中查找原始单词留作练习。

【讨论】:

  • 所以有了那个新函数,我可以在 get-unique 函数中运行它,然后我就可以使用 tihs (defn print-map [m] (prn "print map", m) (for [[x,y] (seq m)] (println (str x " : " y)))) 之类的东西打印出地图
  • 我不确定你到底在想什么,但我怀疑你还没有理解关于不变性的观点。在 repl 中尝试一下,看看它的作用。
  • 我试图做的是例如“门”“路德”“气味”“笔”的输入。只返回“pen”,因为当其他人被排序时,它们是同一个词。 "pen" 是唯一一个不能由任何其他字符串组成的字符串
猜你喜欢
  • 1970-01-01
  • 2012-07-02
  • 2015-08-02
  • 2012-06-12
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
相关资源
最近更新 更多