2014-08-30 3 views
1

Voici ce que j'ai:Ajout des valeurs aux vecteurs et ensembles

(def my-atom (atom [])) 

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

Comment puis-je Ajoutant au vecteur que si elle est présente pas déjà? Je veux être en mesure d'utiliser un prédicat pour le test. Par exemple, dans Common Lisp il y a pushnew:

pushnew item place &key key test test-not 

Y at-il quelque chose de similaire à Clojure? Peut-être, je devrais utiliser des ensembles au lieu de vecteurs. Bien. Comment définissez-vous le prédicat que cet ensemble utilisera pour comparer ses valeurs? Par exemple, l'ensemble peut contenir des chaînes, et supposer que les différences dans le cas ne devraient pas affecter les opérations sur les ensembles, comment Clojure traite-t-il de cela?

Répondre

2

L'utilisation d'un vecteur:

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

l'aide d'un jeu avec un comparitor tri personnalisé:

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

Eh bien, merci, je peux en fait écrire quelque chose comme ça aussi, je cherchais une solution standard, déjà implémentée, pour éviter de réinventer la roue. Quoi qu'il en soit, merci. – Mark

+0

notez l'édition - c'est en fait ce pour quoi 'set-set-by' est conçu (si la commande n'est pas importante ici au moins). – noisesmith

+0

Non, commander n'est pas important, mon exemple est simplifié ici, mais en réalité c'est quelque chose comme un dictionnaire de mots. – Mark

2

Si vous ne travaillez pas avec des atomes, la fn pour ajouter un vecteur si ce n'est pas il y aurait:

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

Maintenant, vous pouvez facilement utiliser cette fn pour passer d'une valeur de l'atome le suivant:

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

Selon votre cas d'utilisation, un ensemble peut être plus approprié. Clojure se base sur l'implémentation des équations et des hash-codes des objets que vous mettez dans l'ensemble, sauf si vous utilisez un tri-set-by, ou vous pouvez simplement les mettre en majuscules avant de les placer dans l'ensemble.

+1

vous n'avez pas besoin de compter sur égaux et hashcode si vous utilisez un tri-set par – noisesmith

+0

oublié à propos de ceux-ci. Merci! – DanLebrero