【问题标题】:How to add or update a list in clojure?如何在 clojure 中添加或更新列表?
【发布时间】:2021-11-08 04:35:47
【问题描述】:

我有这个功能,但我不知道如何实现它。我只知道怎么用concat,但是错了,因为它只是添加,我还需要更新。

谁能帮帮我?

这是函数:

(defn update-env 
  [env-global key value]
  (if (and (list? value) (= (first value) '*error*))
    env-global
    (concat env-global (list key value))))

这是我需要运行的代码: (update-env '(+ add - sub x 1 y 2) 'x 3)

这是它应该给出的结果: (+ add - sub x 3 y 2)

提前致谢!

【问题讨论】:

标签: clojure


【解决方案1】:

诀窍是成对地操作集合的元素,类似于常见的 lisp 的plist。你可以这样编:

(defn plist-assoc [key new-val plist]
  (->> plist
       (partition 2)
       (mapcat (fn [[k v]] [k (if (= k key) new-val v)]))))

user> (plist-assoc 'x 3 '(+ add - sub x 1 y 2))
;;=> (+ add - sub x 3 y 2)

user> (plist-assoc 'z 3 '(+ add - sub x 1 y 2))
;;=> (+ add - sub x 1 y 2)

所以你的函数看起来像这样:

(defn update-env [env-global key value]
  (if (and (list? value) (= (first value) '*error*))
    env-global
    (plist-assoc key value env-global)))

user> (update-env '(+ add - sub x 1 y 2) 'x 3)
;;=> (+ add - sub x 3 y 2)

更新 如果你需要更新或插入新值,你可以使用类似的东西:

(defn assoc-plist2 [key new-val plist]
  (let [[l r] (->> plist
                   (partition 2)
                   (split-with (comp nil? #{key} first)))]
    (apply concat `(~@l ~[key new-val] ~@(rest r)))))

user> (assoc-plist2 'x 10 '(+ add - sub x 1 y 2))
;;=> (+ add - sub x 10 y 2)

user> (assoc-plist2 'z 10 '(+ add - sub x 1 y 2))
;;=> (+ add - sub x 1 y 2 z 10)

【讨论】:

  • 此解决方案不会添加新对 - (update-env '(+ add - sub x 1 y 2) 'z 3) 返回相同的环境。
  • @MartinPůda,谢谢!更新了我的答案
【解决方案2】:

您可以将env-global 表示为哈希映射并使用assoc 进行更新:

(defn update-env [env-global key value]
  (if (and (list? value)
           (= (first value) '*error*))
    env-global
    (assoc env-global key value)))

(update-env '{+ add - sub x 1 y 2} 'x 3)

或者您可以使用列表并将其转换为哈希映射并返回(已编辑):

(defn env->map [env]
  (apply hash-map env))

(defn map->env [m]
  (->> m
       (apply list)
       (apply concat)))

(-> (env->map '(+ add - sub x 1 y 2))
    (update-env 'x 3)
    (map->env))

【讨论】:

  • flatten 在几乎所有情况下都是一颗定时炸弹。例如,如果您的环境是{x (a b c)},该怎么办?你会不小心产生(x a b c) 而不是(x (a b c))。而是使用 apply concat 之类的东西。
猜你喜欢
  • 2017-02-27
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多