如何生成在Clojure中编写的循环中循环的旋转序列
在计划晚餐菜单时,用户希望先轮换3天肉,然后再轮换一道素食主菜。肉的轮换是牛肉、鸡肉、鱼、猪肉。蔬菜的轮换方式是先搅拌,然后是豆腐。有没有比我下面介绍的更好(更优雅、更简洁、更可读)的方法来生成用餐顺序如何生成在Clojure中编写的循环中循环的旋转序列,clojure,Clojure,在计划晚餐菜单时,用户希望先轮换3天肉,然后再轮换一道素食主菜。肉的轮换是牛肉、鸡肉、鱼、猪肉。蔬菜的轮换方式是先搅拌,然后是豆腐。有没有比我下面介绍的更好(更优雅、更简洁、更可读)的方法来生成用餐顺序 (defn menu [n] (let [meat (cycle '[:beef :chicken :fish :pork]) veg (cycle '[:stirfry :tofu])] (take n (mapcat
(defn menu [n] (let [meat (cycle '[:beef :chicken :fish :pork])
veg (cycle '[:stirfry :tofu])]
(take n (mapcat seq (interleave (partition 3 meat) (partition 1 veg))))))
我想这本书略短,更容易阅读(可能更快): 答复:
user> (menu 10)
(:beef :chicken :fish :tofu :pork :beef :chicken :stirfry :fish :pork)
由于mapcat
可以进行大量的收集,因此就可以了
(conj(:牛肉:鸡肉:鱼):奶油)
(conj(:猪肉:牛肉:鸡肉):豆腐)
等等
您只需要删除第一个值,因为conj
with list会在开头添加一个元素
如果可以从素食餐开始,那么你也可以减少休息时间,缩短时间
(以n(mapcat conj(分区3肉)蔬菜)为例)
我很想概括一下这个问题:
- 接受任意比例的任意数量的主菜
- 生成整个延迟序列,将客户端作为 需要多少就有多少
(def dishes [3 [:beef :chicken :fish :pork]
1 [:stirfry :tofu]])
我们可以调整您的解决方案以生成无休止的菜式序列:
(defn rotate [nlist-pairs]
(let [pairs (partition 2 nlist-pairs)
sources (map (fn [[n xs]] (partition n (cycle xs)))
pairs)]
(apply concat (apply interleave sources))))
要获得前十名
(take 10 (rotate dishes))
;(:beef :chicken :fish :stirfry :pork :beef :chicken :tofu :fish :pork)
不完全是。你的第一道菜是豆腐。应该是斯蒂弗利。在
mapcat
中将veg
替换为(缺点:扔掉veg)
?这真是聪明。我喜欢一个人如何添加许多集合和控制比例,以及你将菜肴定义和比例与选择分开的方式。我这样做的动机并不是真正的菜谱,而是一种在许多团队中共享的职责表,一些大的,一些小的,我希望尽可能少地给他们增加负担。
(take 10 (rotate dishes))
;(:beef :chicken :fish :stirfry :pork :beef :chicken :tofu :fish :pork)