我无法解释为什么原子引用不保留inc的值.
1)如何纠正这个?2)为什么在调试模式下它似乎给出了正确的值?
我知道这可能不是最佳解决方案,但想要理解为什么它不起作用.
你的任务是通过比较a0和b0,a1和b1,a2和b2来找到他们的比较点.
如果a大于b,那么Alice将获得积分.如果a小于b,则Bob获得积分.如果a等于b,那么两个人都没有得到一个点.
(defn compare-the-triplets
[alice bob]
(let [alice-score (atom 0)
bob-score (atom 0)]
(for [i (range 3)]
(let [a (get alice i)
b (get bob i)]
(cond
(> a b) (swap! alice-score inc)
(< a b) (swap! bob-score inc))
)) [@alice-score @bob-score]))
(compare-the-triplets [5 6 7] [3 6 10])
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它为Atom返回0和0.我觉得这可能不是最好的答案,但它真的很烦人为什么调试工作并获得正确值的原子,但然后他们没有正确返回.
使用let和for的范围一定不能正确.
这是冒险进入审查领域,但我认为应该强调原子不是这里的正确工具.没有副作用的泄漏,但它们的使用不必要地使一切都膨胀,并且违背了常见的功能实践.
由于这基本上只是一种减少,这就是我认为最好的.你有一个集合(或者在这种情况下,有两个),需要积累一个值(或者再次,在这种情况下,两个).无论何时出现这种情况,reduce都应该想到:
(defn compare-the-triplets2 [alice bob]
(reduce (fn [scores [al bo]]
; If the condition on the left is true, update either the 0th or 1st score
(cond-> scores
(> al bo) (update 0 inc)
(< al bo) (update 1 inc)))
; Both start with a score of 0
[0 0]
; Zip alice and bob together, then reduce over the zipped collection
(map vector alice bob)))
Run Code Online (Sandbox Code Playgroud)
事实上,平局可能使事情复杂化,但cond->处理得很好.不幸的是,cond->不像是那样短路cond,所以效率会稍差.除非这被证明是时间关键代码,否则时差应该是可以忽略不计的.
注意它的使用update,以及它与你的使用有多相似swap!.在这种情况下,我使用0和1来指示向量累加器中的哪个得分递增.
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |