首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure partition-by:对一些元素进行分组,并保留其他元素不变

Clojure partition-by:对一些元素进行分组,并保留其他元素不变
EN

Stack Overflow用户
提问于 2020-07-06 20:41:38
回答 5查看 158关注 0票数 0

从这里开始有没有一种惯用的方法:

代码语言:javascript
复制
[{:red 1} {:red 2} {:blue 3} {:blue 4} {:red 5} {:blue 6} {:red 7} {:red 8} {:red 9}]

到这里:

代码语言:javascript
复制
 [[{:red 1} {:red 2}] 
  [{:blue 3}] 
  [{:blue 4}] 
  [{:red 5}] 
  [{:blue 6}] 
  [{:red 7} {:red 8} {:red 9}]]

也就是说,任何连续的红色被组合在一起,但每个蓝色作为一个单独的组?

谢谢。

EN

回答 5

Stack Overflow用户

发布于 2020-07-06 20:55:26

可以使用partition-by对序列中的连续值进行分组:

代码语言:javascript
复制
(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密钥进行分组。所以我们可以为它构造特定的函数:

代码语言:javascript
复制
(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}))
票数 2
EN

Stack Overflow用户

发布于 2020-07-06 20:56:01

下面是一个简单的方法:

代码语言:javascript
复制
(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的使用让你感到有点不满意,下面是使用当前时间(精确到纳秒)而不是随机数的替代方案,这保证在连续的过程中总是产生不同的结果:

代码语言:javascript
复制
(partition-by #(if (:red %) :const (java.time.LocalDateTime/now)) x)
票数 1
EN

Stack Overflow用户

发布于 2020-07-06 21:27:49

先做工作,然后部分撤销可能有点笨拙,但至少在边界情况下是相对安全的(:blue的值是相同的),并且实际上将任何非red分开。

代码语言:javascript
复制
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}])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62756320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档