从这里开始有没有一种惯用的方法:
[{:red 1} {:red 2} {:blue 3} {:blue 4} {:red 5} {:blue 6} {:red 7} {:red 8} {:red 9}]到这里:
[[{:red 1} {:red 2}]
[{:blue 3}]
[{:blue 4}]
[{:red 5}]
[{:blue 6}]
[{:red 7} {:red 8} {:red 9}]]也就是说,任何连续的红色被组合在一起,但每个蓝色作为一个单独的组?
谢谢。
发布于 2020-07-06 20:55:26
可以使用partition-by对序列中的连续值进行分组:
(partition-by ffirst [{:red 1} {:red 2} {:blue 3} {:blue 4} {:red 5} {:blue 6} {:red 7} {:red 8} {:red 9}])
;; => (({:red 1} {:red 2})
;; ({:blue 3} {:blue 4})
;; ({:red 5})
;; ({:blue 6})
;; ({:red 7} {:red 8} {:red 9}))我看到在您的例子中,您只想对:red密钥进行分组。所以我们可以为它构造特定的函数:
(partition-by #(or (contains? % :red) %)
[{:red 1} {:red 2} {:blue 3} {:blue 4} {:red 5} {:blue 6} {:red 7} {:red 8} {:red 9}])
;; => (({:red 1} {:red 2})
;; ({:blue 3})
;; ({:blue 4})
;; ({:red 5})
;; ({:blue 6})
;; ({:red 7} {:red 8} {:red 9}))发布于 2020-07-06 20:56:01
下面是一个简单的方法:
(def x [{:red 1} {:red 2} {:blue 3} {:blue 4} {:red 5} {:blue 6} {:red 7} {:red 8} {:red 9}])
(partition-by #(if (:red %) :const (rand)) x)
;; =>(({:red 1} {:red 2})
;; ({:blue 3})
;; ({:blue 4})
;; ({:red 5})
;; ({:blue 6})
;; ({:red 7} {:red 8} {:red 9}))partition-by所做的就是在集合中的每个元素上运行一个函数,当我们得到一个不同的值时将其拆分。在这种情况下,我们需要构造一个自定义函数,该函数根据map的键是:red还是其他值(例如:blue)进行分支,始终为:red返回相同的内容(例如,关键字:const之类的常量),但对于:blue等其他键始终返回不同的内容(这可以通过rand等随机函数来完成)。
我们给它的匿名函数,#(if (:red %) :const (rand))就是这样做的--检查键值是否为:red,然后根据它发出一个分支返回值。
然而,正如@cfrick在一条评论中提到的那样,人们担心连续两次获得相同的随机数-非常不可能,但仍然是一个令人担忧的问题。如果rand的使用让你感到有点不满意,下面是使用当前时间(精确到纳秒)而不是随机数的替代方案,这保证在连续的过程中总是产生不同的结果:
(partition-by #(if (:red %) :const (java.time.LocalDateTime/now)) x)发布于 2020-07-06 21:27:49
先做工作,然后部分撤销可能有点笨拙,但至少在边界情况下是相对安全的(:blue的值是相同的),并且实际上将任何非red分开。
user=> (sequence
(comp
(partition-by #(contains? % :red))
(mapcat #(if (-> % first (contains? :red))
[%]
(map vector %))))
[{:red 1} {:red 2} {:blue 3} {:blue 3} {:red 5}])
([{:red 1} {:red 2}]
[{:blue 3}]
[{:blue 3}]
[{:red 5}])https://stackoverflow.com/questions/62756320
复制相似问题