Clojure 使用循环递归计算winrate
我得到了以下代码,Clojure 使用循环递归计算winrate,clojure,clojurescript,Clojure,Clojurescript,我得到了以下代码,calc winrate在最后一行返回[0 0 50 0 25]。我正在尝试使其返回[0 50 33.33333333333 50 60] 我是否为wins执行增量错误?当我为每次迭代打印wins的值时 (defn to-percentage [wins total] (if (= wins 0) 0 (* (/ wins total) 100))) (defn calc-winrate [matches] (let [data (r/atom [])]
calc winrate
在最后一行返回[0 0 50 0 25]
。我正在尝试使其返回[0 50 33.33333333333 50 60]
我是否为wins
执行增量错误?当我为每次迭代打印wins
的值时
(defn to-percentage [wins total]
(if (= wins 0) 0
(* (/ wins total) 100)))
(defn calc-winrate [matches]
(let [data (r/atom [])]
(loop [wins 0
total 0]
(if (= total (count matches))
@data
(recur (if (= (get (nth matches total) :result) 1)
(inc wins))
(do
(swap! data conj (to-percentage wins total))
(inc total)))))))
(calc-winrate [{:result 0} {:result 1} {:result 0} {:result 1} {:result 1}])
所以我猜我是以某种方式重置还是以某种方式nil获胜
另外,整个循环是否可以用map/map索引之类的东西来代替?感觉map非常适合使用,但每次迭代我都需要记住上一次迭代的wins/total
谢谢 这里有一个使用reduce的解决方案:
0
nil
1
nil
1
因此,这里要做的是维护(和更新)到目前为止的计算状态。
我们在地图上这样做那是
(defn calc-winrate [matches]
(let [total-matches (count matches)]
(->> matches
(map :result)
(reduce (fn [{:keys [wins matches percentage] :as result} match]
(let [wins (+ wins match)
matches (inc matches)]
{:wins wins
:matches matches
:percentage (conj percentage (to-percentage wins matches))}))
{:wins 0
:matches 0
:percentage []}))))
胜利将包含迄今为止的胜利,比赛是我们分析的比赛数量,百分比是迄今为止的百分比
{:wins 0
:matches 0
:percentage []}
您的if应写如下:
(if (= (get (nth matches total) :result) 1)
(inc wins))
如果你选择一个
(if (= (get (nth matches total) :result) 1)
(inc wins)
wins ; missing here , other wise it will return a nil, binding to wins in the loop
)
这是一个懒惰的解决方案,它使用reductions
获得一系列运行中的赢家总数,并使用传感器1)将整数与运行中的总数相加2)将两个对分开3)将分数转换为百分比:
(defn calc-winrate2 [ x y ]
(let [ {total :total r :wins } x
{re :result } y]
(if (pos? re )
{:total (inc total) :wins (inc r)}
{:total (inc total) :wins r}
)
)
)
(reductions calc-winrate2 {:total 0 :wins 0} [ {:result 0} {:result 1} {:result 0} {:result 1} {:result 1}])
您可以按如下方式计算跑步赢取率:
(defn calc-win-rate [results]
(->> results
(map :result)
(reductions +)
(sequence
(comp
(map-indexed (fn [round win-total] [win-total (inc round)]))
(map (partial apply /))
(map #(* 100 %))
(map float)))))
(calc-win-rate [{:result 0} {:result 1} {:result 0} {:result 1} {:result 1}])
=> (0.0 50.0 33.333332 50.0 60.0)
比如说,
(defn calc-winrate [matches]
(map
(comp float #(* 100 %) /)
(reductions + (map :result matches))
(rest (range))))
map
在两个序列上运行:
(减少+(映射:结果匹配))
-持续的赢家总数李>
(剩余(范围)))
-(1 2 3…
,对应的匹配数李>
映射
ping函数,(comp float#(*100%)/)
- 将序列中的相应元素分开
- 乘以100
- 将其转换为浮点
当我转换成带有(转换为[]
的向量时,我会得到新行上的每个条目,有什么线索吗?@Olle你是说结果会跨REPL中的多行打印吗?这是由REPL设置控制的,请参见。这不会影响结果的值,只会影响结果的打印方式。非常好地使用了带有多个集合输入的映射
=> (calc-winrate [{:result 0} {:result 1} {:result 0} {:result 1} {:result 1}])
(0.0 50.0 33.333332 50.0 60.0)