2010-06-25 136 views
22

我想编写一个函数,如果给定的集合不为空,将返回布尔值true,否则返回false。什么是正确的“clojure方式”来检查一个集合是否为空

我既可以做

defn .. 
(boolean (seq coll)) 

defn .. 
(not (empty? coll)) 

由于我是新来的Clojure我最初倾向于去与#2(更易读),但empty? Clojure的API参考明确表示使用成语(seq coll)而不是(not (empty? coll)),也许是为了避免双重否定。

我想知道什么是clojure方式来检查一个集合是否为非空并返回一个布尔值true/false。

回答

12

从中尤其是这样的nonempty?功能不应该是必要的,甚至是特别有用提到的手段,因为seq能够始终站在它在布尔上下文,empty?的文档字符串的通道,该通道在纯粹的Clojure代码它能够。

如果你觉得不得不写这样一个函数,我会说我更喜欢第一种方法。无论如何,empty?建立在seq上,因此无法避免调用它;只是将结果转换为布尔值似乎比通过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 
    
+6

事实上,我们可以'(defalias truthy?boolean)'。 – 2010-06-25 18:45:28

4

除了米哈尔Marczyk的出色答卷,我会指出,有一个具体的不是空功能:

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

但你问什么它没有做。 (虽然它可以在大多数情况下工作)。

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

+6

对谓词使用非空是愚蠢的。在谓词上下文中,not-empty只是seq的一个冗长而缓慢的版本。非空的真正用途是当你想在测试虚空时“让”本地,而不是通过顺序视图破坏类型信息:'(if-let [coll(not-empty coll)] ... )'。例如,如果coll是一张地图,则可以在不转换为seq的情况下测试虚拟空间。 – amalloy 2011-07-15 20:13:46

+2

@amalloy'not-empty'更具可读性,更低层次,然后是'seq',并且具有完全相同的速度,您可以在https://github.com/clojure/clojure/blob查看其源代码/clojure-1.7.0/src/clj/clojure/core.clj#L5302 – alesguzik 2016-03-11 14:35:54

26

根据的Clojure,的喜悦比零seq夯实是地道:

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

” ......使用seq作为终止条件是测试序列是否是空的惯用方式。如果我们测试[在上面的例子中]只是s而不是(seq s),那么即使对于空集合也不会发生终止条件......“

相关问题