4 Réponses :
Voici une solution avec réduire:
{:wins 0 :matches 0 :percentage []}
Il s'agit donc ici de maintenir (et de mettre à jour) l'état du calcul jusqu'à présent. Nous faisons cela dans la carte qui est
(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 []}))))
Les victoires contiendront les victoires jusqu'à présent, les matchs sont le nombre de matchs que nous avons analysés et le pourcentage est le pourcentage jusqu'à présent.
(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}])
Voici une solution paresseuse utilisant des réductions
pour obtenir une séquence de totaux de gains en cours, et les transducteurs pour 1) joindre les nombres ronds avec les totaux en cours 2) diviser les paires 3) convertir les fractions en pourcentages:
(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)
Quand je convertis en vecteur avec (en []
j'obtiens chaque entrée sur une nouvelle ligne, une idée pourquoi?
@Olle voulez-vous dire que le résultat s'imprime sur plusieurs lignes dans la REPL? Cela est contrôlé par un paramètre REPL, voir cette question . Cela n'affecte pas la valeur du résultat, seulement la façon dont il est imprimé.
Vous pouvez calculer les taux de victoire en cours comme suit:
=> (calc-winrate [{:result 0} {:result 1} {:result 0} {:result 1} {:result 1}]) (0.0 50.0 33.333332 50.0 60.0)
Par exemple,
(defn calc-winrate [matches] (map (comp float #(* 100 %) /) (reductions + (map :result matches)) (rest (range))))
La carte
fonctionne sur deux séquences:
(reductions + (map: result matches))
- le total cumulé des victoires; (rest (range))))
- (1 2 3 ...)
, le nombre correspondant de correspondances. La fonction ping map
, (comp float # (* 100%) /)
,
Très belle utilisation de map
avec plusieurs entrées de collection