你怎么称呼那个函数?看起来您正在传递一个集合,因此它的瞬态版本也将是一个集合,因此不能与任何assoc
函数一起使用,因为它们适用于关联数据结构和向量:
user=> (assoc #{} :a 1)
ClassCastException clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:691)
user=> (assoc! (transient #{}) :a 1)
ClassCastException clojure.lang.PersistentHashSet$TransientHashSet cannot be cast to clojure.lang.ITransientAssociative clojure.core/assoc! (core.clj:2959)
; the following works as it uses maps and vectors
user=> (assoc {} :a 1)
{:a 1}
user=> (assoc! (transient {}) :a 1)
#<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@65cd1dff>
user=> (assoc [] 0 :a)
[:a]
现在,让我们尝试讨论代码本身。遵循您的代码并尝试理解目标的真正含义有点困难,而无需对您想要实现的目标提供更多提示,但作为一般性评论:
您有一个times
根本不使用的输入参数
你应该使用瞬态突变的结果,而不是假设瞬态会原地突变
如果可以,请避免瞬变,它们仅用于性能优化
绑定_current (/ _count 2)
可能不是您想要的,因为(/ 5 2)
确实返回5/2
了,并且您似乎想将其用作结果中的位置
常量_count
不需要成为loop
绑定的一部分,您可以使用外部let
,这样您就不必在每次迭代时都传递它们
使用let
而不是def
在函数中命名事物
(if ((rem 1 2) = 0))
绝对不是你想要的
现在,抛开洗牌算法,如果你需要重新排列一个序列,你可能只需要产生一个新位置序列,map
它们与原始卡片产生对,[position card]
最后reduce
通过将卡片放置在新位置,使用原始序列来产生对作为种子:
(defn generate [coll] ; counts down from (count coll) to 0, change to
; implement your shuffling algorithm
(range (dec (count coll)) -1 -1))
(defn mongean [cards times]
(let [positions (generate cards) ; get the new positions
assemble (fn [dest [pos card]] ; assoc the card at the wanted position
(assoc dest pos card))]
(reduce assemble cards (map vector positions cards))))
如果你只是想洗牌:
(defn mongean [cards times] (shuffle cards))