如何用循环简化re-frame中8段重复的doseq代码?
解决方案
直接通过嵌套doseq遍历即可,外层遍历所有关键词,内层遍历对应集合的元素,同时可以直接使用当前关键词做条件判断,完全避免重复代码:
(let [parts [:one :two :three :four :five :six :seven :eight] ;; 替换成你实际的订阅调用,比如@(subscribe [:get-my-collection]) my-collection @my-collection-atom] (doseq [part parts] (doseq [each (get my-collection part)] ;; 编写你的逻辑,part就是当前遍历到的关键词(如:one、:four等) (when (= part :one) ;; 处理:one对应的元素逻辑 ) (when (= part :four) ;; 处理:four对应的元素逻辑 ) (when (= part :eight) ;; 处理:eight对应的元素逻辑 ) ;; 其他通用逻辑或条件判断 )))
如果不同关键词的逻辑分支较多,用cond替代多个when会更清晰:
(let [parts [:one :two :three :four :five :six :seven :eight] my-collection @my-collection-atom] (doseq [part parts] (doseq [each (get my-collection part)] (cond (= part :one) ;; :one专属逻辑 (= part :four) ;; :four专属逻辑 (= part :eight) ;; :eight专属逻辑 :else ;; 其他关键词的默认逻辑(可选) ) ;; 所有元素都要执行的通用逻辑 )))
你之前代码的问题
- 没必要手动维护索引:Clojure的序列遍历不需要用
atom记录索引,直接用doseq遍历parts即可,代码更简洁且符合函数式风格。 - 语法错误:你的
if语句都缺少闭合括号(比如(if (= :one (nth parts @index)末尾少了)),导致代码无法运行。 - recur参数错误:
recur时传递的是关键词((nth parts @index)),但loop绑定的each应该是该关键词对应的集合,逻辑不匹配。
内容的提问来源于stack exchange,提问作者niloofar
相关产品推荐
相关产品推荐

