向向量和集添加值

时间:2014-08-30 13:56:32

标签: vector clojure set append

这就是我所拥有的:

(def my-atom (atom []))

(defn add-to-my-atom! [x]
  (swap! my-atom conj x))

如果向量值已经存在,我如何将值附加到向量中?我希望能够使用谓词进行测试。例如,在Common Lisp中有pushnew

pushnew item place &key key test test-not

Clojure中有类似的东西吗?也许,我应该使用集合而不是向量。精细。如何定义set将用于比较其值的谓词?例如,set可以包含字符串,并假设案例中的差异不应影响集合上的操作,Clojure如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:2)

如果你没有使用原子,那么添加到矢量的fn如果不存在则会出现:

(defn push-new [v value]
   (if (some #{value} v)
       v
       (conj v value)))

现在您可以轻松地使用该fn从原子的一个值移动到下一个:

(defn add-to-my-atom [the-atom x]
   (swap! the-atom push-new x))

根据您的使用情况,一组可能更合适。 Clojure依赖于放入集合中的对象的equals和hashcode实现,除非你使用sorted-set-by,或者你可以在将它们放入集合之前简单地将它们大写。

答案 1 :(得分:2)

使用矢量:

user> (def my-atom (atom []))

(defn push-new
  [place item pred]
  (if (pred place item)
    (conj place item)
    place))

(defn add-to-my-atom!
  [x]
  (swap! my-atom push-new x
         (fn [place item]
           (not (some #(= (.toLowerCase %)
                          (.toLowerCase item))
                      place)))))


#'user/add-to-my-atom!
user> (add-to-my-atom! "Hello World!")
["Hello World!"]
user> (add-to-my-atom! "hello world!")
["Hello World!"]
user> (add-to-my-atom! "ABCDE")
["Hello World!" "ABCDE"]
user> (add-to-my-atom! "abcde")
["Hello World!" "ABCDE"]

使用带有自定义排序比较器的集合:

user> (def my-atom (atom (sorted-set-by (fn [a b] (compare (.toLowerCase a) (.toLowerCase b))))))
#'user/my-atom
user> (swap! my-atom conj "Hello")
#{"Hello"}
user> (swap! my-atom conj "hello")
#{"Hello"}
user> (swap! my-atom conj "abc")
#{"abc" "Hello"}
user> (swap! my-atom conj "Abc")
#{"abc" "Hello"}