检查集合是否为空的正确“clojure方式”是什么

时间:2010-06-25 14:50:56

标签: clojure

我想编写一个函数,如果给定集合不为空,则返回布尔值true,否则返回false。

我可以做到

defn ..
(boolean (seq coll))

defn ..
(not (empty? coll))

由于我是clojure的新手,我最初倾向于使用#2(更具可读性),但empty?的clojure api参考明确表示使用成语(seq coll)而不是{{1} },也许是为了避免双重否定。

我想知道检查集合是否为非空的clojure方法是什么,并返回布尔值true / false。

4 个答案:

答案 0 :(得分:26)

根据Clojure的喜悦, nil punning seq是惯用的:

(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

“...使用seq作为终止条件是测试序列是否为空的惯用方法。如果我们[在上面的例子中]测试了s而不是{{ 1}},即使对于空集合也不会发生终止条件......“

答案 1 :(得分:12)

你提到的empty?文档字符串的段落特别意味着这样的nonempty?函数永远不是必需的,甚至特别有用,因为seq总是可以代表它在布尔上下文中,在纯Clojure代码中它可以。

如果您觉得有必要编写这样的功能,我会说我更喜欢第一种方法。 empty?无论如何都建立在seq之上,因此无法避免调用它;将结果转换为Boolean似乎比通过not的两次旅行更清晰。有关其他选项,请参阅例如nil?false?(我还是喜欢演员)。

顺便说一下,你为什么要写这个...?用于调用带有boolean参数的Java方法?在这种情况下,我认为演员会很好地表达意图。

更新:举例说明后一点:

  1. 一个简单的Java类:

    public class Foo {
      public static boolean foo(boolean arg) {
        return !arg;
      }
    }
    
  2. 一些Clojure客户端代码:

    (Foo/foo nil)
    ; => NullPointerException
    (Foo/foo (boolean nil))
    ; => true
    

答案 2 :(得分:4)

除了Michal Marczyk的优秀答案之外,我还会指出有一个特定的非空函数:

http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty

但它并不完全符合您的要求。 (虽然它适用于大多数情况)。

如果集合为空,则非空返回nil,如果集合不为空,则返回集合本身。对于谓词测试,这将运行良好。如果你真的需要真值和假值,那么(不是(空?x))就是你所追求的。

答案 3 :(得分:0)

如果您需要布尔值,我认为(comp not seq)的含义很不错。

用法示例:

((comp not seq) coll)

如果以后需要将其存储为fn:

(def not-empty' (comp not seq))
相关问题