Clojure 按过滤器分区

标签 clojure partitioning

在 Scala 中,分区方法将一个序列拆分为两个单独的序列——谓词为真的序列和谓词为假的序列:

scala> List(1, 5, 2, 4, 6, 3, 7, 9, 0, 8).partition(_ % 2 == 0)
res1: (List[Int], List[Int]) = (List(2, 4, 6, 0, 8),List(1, 5, 3, 7, 9))

请注意 Scala 实现 只遍历一次序列 .

在 Clojure 中 partition-by函数将序列拆分为多个子序列,每个子序列都是满足或不满足谓词的最长子集:
user=> (partition-by #(= 0 (rem % 2)) [1, 5, 2, 4, 6, 3, 7, 9, 0, 8])
((1 5) (2 4 6) (3 7 9) (0 8))

split-by产生:
user=> (split-with #(= 0 (rem % 2)) [1, 5, 2, 4, 6, 3, 7, 9, 0, 8])
[() (1 5 2 4 6 3 7 9 0 8)]

是否有一个内置的 Clojure 函数与 Scala 做同样的事情 partition方法?

最佳答案

我相信您正在寻找的功能是 clojure.core/group-by .它返回一个键映射到原始序列中的项目列表,分组函数为其返回该键。如果您使用真/假生成谓词,您将获得您正在寻找的拆分。

user=> (group-by even? [1, 5, 2, 4, 6, 3, 7, 9, 0, 8])
{false [1 5 3 7 9], true [2 4 6 0 8]}

如果你看看the implementation ,它满足您只使用一次通行证的要求。另外,它在引擎盖下使用 transient ,因此它应该比迄今为止发布的其他解决方案更快。一个警告是您应该确定您的分组功能产生的键。如果它产生 nil而不是 false ,那么您的 map 将在 nil 键下列出失败的项目。如果您的分组函数产生非 nil 值而不是 true,那么您可以在多个键下列出传递值。不是什么大问题,只需注意您需要为分组函数使用真/假生成谓词。

关于 group-by 的好处是它比将序列拆分为通过和失败的项目更通用。您可以轻松地使用此功能将您的序列分组为您需要的任意多个类别。非常有用和灵活。这可能就是为什么 group-byclojure.core而不是 separate .

关于Clojure 按过滤器分区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5664833/

相关文章:

string - 如何从字符串 Clojure 中删除反斜杠\

mysql - 如何在此表上使用 MySQL 表分区?

mysql - MySQL 5.5 (InnoDB) 的分区策略

performance - Clojure 应用程序启动性能

java - 如何在 Clojure 中引用原始 Java 类型?

Mysql分区对索引的影响

sql - 如何在 SQL 2005 中获取分区范围

sql - 在Oracle SQL中,我可以查询表的一个分区而不是整个表以使其运行得更快吗?

clojure - Clojure 中的 make-keyword-map - 惯用语?

clojure - 跨多个命名空间使用 clojure 协议(protocol)