首页 > 解决方案 > 循环遍历向量的向量并从 Clojure 中的向量中删除元素

问题描述

我是 clojure 编程的新手,想要一些代码方面的帮助。我有这个向量的向量,如下所示,

(def start-pos [[[:fox :goose :corn :you] [:boat] []]])

我想遍历向量并从内部向量之一中删除一个元素,例如从 start-pos 中删除 ':goose'。

我尝试了下面的代码,但由于某种原因它不能按预期工作,

(map #(disj (set %) :goose) start-pos)

结果是,

(#{[:boat] [] [:fox :goose :corn :you]})

正如您从结果中看到的那样,内部向量现在是一个集合,是的,原始顺序被扭曲了,有没有办法删除元素而不打乱向量的原始顺序,可能不需要先将其转换为集合? 我首先选择将此转换为集合,因为根据文档disj仅适用于集合。

补充:这篇文章与这个建议的帖子不相似,因为我的向量嵌套了三个向量深。

标签: clojureclojurescript

解决方案


内部向量现在是一组

那是因为#(disj (set %) :goose)返回一个集合的结果。

原来的顺序被扭曲了

默认情况下,集合不保留插入顺序,类似于超过 8 个键的映射。

我想循环遍历向量并从内部向量之一中删除一个元素,例如从 start-pos 中删除 ':goose'。

调用谓词从集合中删除元素所需的函数remove,但是...

您要删除的值实际上是嵌套在 中的三个向量start-pos,因此如果您想:goose递归地从每个向量中删除关键字,则需要对每个内部向量进行额外的迭代,依此类推。这是使用的借口clojure.walk

(clojure.walk/postwalk
  (fn [v]
    (if (coll? v)
      (into (empty v) (remove #{:goose}) v)
      v))
  start-pos)
=> [[[:fox :corn :you] [:boat] []]]

这会遍历 中的每个值start-pos:goose从它找到的任何集合中删除。


推荐阅读