61 votes

Quelle est la manière idiomatique d’ajouter un vecteur dans Clojure?

Ajoutant à une liste est facile:

user=> (conj '(:bar :baz) :foo)
(:foo :bar :baz)

Ajout d'un vecteur est facile:

user=> (conj [:bar :baz] :foo) 
[:bar :baz :foo]

Comment puis-je (idiomatique) ajouter un vecteur, alors que le retour d'un vecteur? Cela ne fonctionne pas car il renvoie une séquence, pas un vecteur:

user=> (cons :foo [:bar :baz])     
(:foo :bar :baz)

C'est moche (AMHA):

user=> (apply vector (cons :foo [:bar :baz])) 
[:foo :bar :baz]

Remarque: en gros, je veux juste un discbased que je peut ajouter et ajouter. L'ajout de listes de grande taille devraient avoir une grande performance peine, alors j'ai pensé à des vecteurs..

79voto

kotarak Points 11177

Les vecteurs ne sont pas conçus pour l'ajout anticipé. Vous avez seulement O (n) prepend:

 user=> (into [:foo] [:bar :baz])
[:foo :bar :baz]
 

Ce que vous voulez, c'est probablement un arbre à doigts .

18voto

Bill Burdick Points 169

Je sais que cette question est ancienne, mais personne ne dit rien à propos de la différence listes et puisque vous dites que vous avez vraiment veulent juste quelque chose que vous pouvez ajouter et d'ajouter avec, il semble que la différence les listes peuvent vous aider. Ils ne semblent pas populaire en Clojure, mais ils sont TRÈS faciles pour mettre en œuvre et beaucoup moins complexe que doigt les arbres, j'ai donc fait un petite différence liste de la bibliothèque, tout à l'heure (et même testé). Ces concaténer en O(1) temps (ajouter ou ajouter). La conversion d'une différence liste retour à la liste devrait vous coûter O(n), qui est un joli compromis si vous êtes en train de faire beaucoup de concaténation. Si vous ne faites pas beaucoup de la concaténation, il suffit ensuite de coller à des listes, à droite? :)

Voici les fonctions de cette petite bibliothèque:

dl: Une différence liste est en fait une fonction qui concats son propre contenu de l'argument et retourne la liste obtenue. Chaque fois vous produire une différence de liste, vous êtes en train de créer une petite fonction qui agit comme une structure de données.

dlempty: l'existence d'une différence de liste juste concats son contenu à l' argument, un vide différence liste est la même chose que l'identité fonction.

undl: à Cause de quoi la différence les listes, vous pouvez convertir un différence liste pour une liste normale juste en l'appelant à néant, si ce la fonction n'est pas vraiment nécessaire, c'est juste pour des raisons de commodité.

dlcons: conses un élément à l'avant de la liste -- pas totalement nécessaire, mais consing est une commune assez de fonctionnement et c'est juste une one-liner (comme toutes les fonctions, ici).

dlappend: concats deux différence les listes. Je pense que sa définition est le plus amusant -- check it out! :)

Et maintenant, voici que la minuscule bibliothèque -- 5 une ligne de fonctions qui vous donnent un O(1) ajouter/ajouter des données de la structure. Pas mal, hein? Ah, la beauté de Lambda Calcul...

(defn dl
  "Return a difference list for a list"
  [l]
  (fn [x] (concat l x)))

; Return an empty difference list
(def dlempty identity)

(defn undl
  "Return a list for a difference list (just call the difference list with nil)"
  [aDl]
  (aDl nil))

(defn dlcons
  "Cons an item onto a difference list"
  [item aDl]
  (fn [x] (cons item (aDl x))))

(defn dlappend
  "Append two difference lists"
  [dl1 dl2]
  (fn [x] (dl1 (dl2 x))))

Vous pouvez le voir en action avec ceci:

(undl (dlappend (dl '(1 2 3)) (dl '(4 5 6))))

qui renvoie:

(1 2 3 4 5 6)

Cela revient aussi la même chose:

((dl '(1 2 3)) '(4 5 6))

Amusez-vous avec la différence les listes!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X