J'utilise Clojure et je dois courir une petite simulation. J'ai un vecteur de longueur n (n est généralement compris entre 10 et 100) qui détient des valeurs. Sur chaque tour de simulation (peut-être 1000 tours ensemble), l'une des valeurs du vecteur est mise à jour au hasard. Je suppose que je pouvais le faire en utilisant un tableau Java et en appelant la méthode ASET, mais cela enfreindrait la programmation fonctionnelle / Immutabilité Idiom. P>
Y a-t-il un moyen plus fonctionnel de le faire, ou devrais-je simplement aller avec le tableau Java? P>
4 Réponses :
Ce n'est pas que Clojure ne vous laisse pas changer de valeur, c'est un peu plus encombrant. Pour examiner les valeurs dans le vecteur changé, utilisez @ VEC-REF. p> pourrait être désactivé dans les détails - je ne suis pas près d'une replaction, malheureusement. Mais cela devrait vous aider à démarrer. P> p>
Merci, je vérifierai également cette façon de résoudre le problème.
(defn run-sim [arr num-iters update-fn] (if (zero? num-iters) arr (let [i (rand-int (count arr)) x (update-fn)] (println "setting arr[" i "] to" x) (recur (assoc arr i x) (dec num-iters) update-fn)))) user> (run-sim [1 2 3 4 5 6 7 8 9 10] 10 #(rand-int 1000)) setting arr[ 8 ] to 167 setting arr[ 4 ] to 977 setting arr[ 5 ] to 810 setting arr[ 5 ] to 165 setting arr[ 3 ] to 486 setting arr[ 1 ] to 382 setting arr[ 4 ] to 792 setting arr[ 8 ] to 478 setting arr[ 4 ] to 144 setting arr[ 7 ] to 416 [1 382 3 486 144 165 7 416 478 10] There's no shame in using a Java array if you need it though. Especially if you need it to go fast. Limit the array-mutation to the inside of your function (clone the input array and work on that maybe) and no one will be the wiser.
permet d'abord définir une fonction qui met à jour un index aléatoire dans un vecteur avec une nouvelle valeur. Notez que le vecteur d'origine n'est pas modifié, un nouveau vecteur (avec la valeur mise à jour) est renvoyé: Cette fonction choisit un index puis d'augmenter ou diminue la valeur à cet indice. Par 1. Vous devez bien sûr changer cette fonction à vos besoins. P> Ensuite, il s'agit d'une matière simple pour composer cette fonction avec elle-même autant de fois que vous souhaitez exécuter la simulation: p>
Merci pour la réponse, cette approche de composation semble également intéressante.
Ajout à la réponse de Brian: Si vous avez besoin de plus de vitesse, vous pouvez également recourir à des transitoires.
Merci! Je vais devoir creuser dans cette affaire transitoire, la vitesse est toujours bonne!
Les transitoires sont faciles: appelez (chose transitoire) au début. Ajouter un ! aux opérations, par exemple. Assoc!, dissocier! etc. Appelez (persistant! TRANSIENT-chose) lorsque vous retournez. Vous ne devez pas fuir les transitoires en dehors de votre fonction, cependant.