(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}])
我得到以下代码,最后一行calc-winrate
返回[0 0 50 0 25]
。我正在尝试使其返回[0 50 33.33333333333333 50 60]
。
我为wins
进行的增量错误吗?当我为每次迭代打印wins
的值时,都会得到
0
nil
1
nil
1
所以我猜我以某种方式重置或为wins
为零?
也可以用map / map-indexed代替整个循环吗?感觉地图会是完美的选择,但每次迭代我都需要牢记先前的迭代获胜/总数。
谢谢!
答案 0 :(得分:1)
这是一个懒惰的解决方案,使用reductions
来获取一系列连续的获胜总数,换能器1)将轮数与连续的总数相加2)除以对3)将分数转换为百分比:
(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)
答案 1 :(得分:1)
您可以如下计算奔跑赢率:
(defn calc-winrate [matches]
(map
(comp float #(* 100 %) /)
(reductions + (map :result matches))
(rest (range))))
例如
=> (calc-winrate [{:result 0} {:result 1} {:result 0} {:result 1} {:result 1}])
(0.0 50.0 33.333332 50.0 60.0)
map
按两个序列进行操作:
(reductions + (map :result matches))
-获胜的总和; (rest (range))))
-(1 2 3 ... )
,对应的匹配数。 map
ping函数(comp float #(* 100 %) /)
,
答案 2 :(得分:0)
这是带有reduce的解决方案:
(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 []}
胜利将包含到目前为止的胜利,比赛是我们分析过的比赛次数,而百分比是到目前为止的百分比。
答案 3 :(得分:0)
(if (= (get (nth matches total) :result) 1)
(inc wins))
您的if如下:
(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
)
如果要减价,
(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}])