【问题标题】:Adding values to vectors and sets向向量和集合添加值
【发布时间】:2014-08-30 13:56:32
【问题描述】:

这是我所拥有的:

(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 可以包含字符串,假设大小写的差异不应该影响对集合的操作,Clojure 是如何处理的?

【问题讨论】:

    标签: vector clojure set append


    【解决方案1】:

    使用向量:

    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"}
    

    【讨论】:

    • 好吧,谢谢,我其实也可以写这样的东西,我一直在寻找一个标准的,已经实现的解决方案,以避免重新发明轮子。无论如何,谢谢。
    • 注意编辑 - 这实际上是 sorted-set-by 的设计目的(如果至少在这里订购不重要的话)。
    • 不,顺序并不重要,我的例子在这里被简化了,但实际上它有点像字典。
    • 在这种情况下,sorted-set-by 具有对数时间查找的优势,而不是使用some 进行线性时间检查
    【解决方案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 依赖于您放入集合中的对象的等号和哈希码实现,除非您使用 sorted-set-by,或者您可以在将它们放入集合之前简单地将它们大写。

    【讨论】:

    • 如果你使用 sorted-set-by,你不需要依赖 equals 和 hashcode
    • 忘记了这些。谢谢!
    猜你喜欢
    • 2012-11-08
    • 2015-08-13
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多