简体   繁体   English

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

[英]What is the correct "clojure way" to check if a collection is non empty

I want to write a function that would return the boolean true if the given collection is not empty and false otherwise.我想编写一个函数,如果给定的集合不为空,则返回布尔值 true,否则返回 false。

I could either do我可以做

defn ..
(boolean (seq coll))

or或者

defn ..
(not (empty? coll))

As I am new to clojure I was initially inclined to go with #2 (more readable), but the clojure api reference for empty?由于我是 clojure 的新手,我最初倾向于使用 #2(更具可读性),但是 clojure api 参考为empty? explicitly says use the idiom (seq coll) instead of (not (empty? coll)) , maybe to avoid double negation.明确表示使用习语(seq coll)而不是(not (empty? coll)) ,也许是为了避免双重否定。

I want to know what is the clojure way to check if a collection is non-empty and return a boolean true/false.我想知道检查集合是否为非空并返回布尔值 true/false 的 clojure 方法是什么。

According to Joy of Clojure, nil punning with seq is idiomatic:根据 Clojure 的喜悦, seq nil 双关语是惯用的:

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

"...the use of seq as a terminating condition is the idiomatic way to test whether a sequence is empty. If we tested [in the above example] just s instead of (seq s) , then the terminating condition wouldn't occur even for empty collections..." “...使用seq作为终止条件是测试序列是否为空的惯用方式。如果我们测试 [在上面的例子中] 只是s而不是(seq s) ,那么终止条件就不会发生即使是空的集合......”

The passage from empty?empty?的通道empty? 's docstring which you mentioned means in particular that such a nonempty?你提到的 docstring 特别意味着这样的nonempty? function should never be necessary, or even particularly useful, because seq can always stand in for it in Boolean contexts, which in pure Clojure code it can.函数永远不是必需的,甚至不是特别有用,因为seq总是可以在布尔上下文中代替它,而在纯 Clojure 代码中它可以。

If you feel compelled to write such a function nonetheless, I'll say that I like the first approach better.尽管如此,如果您觉得有必要编写这样的函数,我会说我更喜欢第一种方法。 empty? is built on seq anyway, so there's no avoiding calling it;无论如何都是建立在seq之上的,所以无法避免调用它; just casting the result to Boolean seems cleaner than two trips through not .只是将结果转换为 Boolean 似乎比通过not两次旅行更干净。 For other options, see eg nil?对于其他选项,请参见例如nil? , false? false? (I still prefer the cast). (我还是更喜欢演员阵容)。

Incidentally, why do you want to write this...?顺便说一句,你为什么要写这个......? For calling a Java method with a boolean argument perhaps?也许是为了使用boolean参数调用 Java 方法? In that case, I think the cast would express the intention nicely.在那种情况下,我认为演员会很好地表达意图。

Update: An example to illustrate the latter point:更新:一个例子来说明后一点:

  1. A simple Java class:一个简单的Java类:

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

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

In addition to Michal Marczyk's excellent answer, I'll point out that there is a specific not-empty function:除了 Michal Marczyk 的出色回答之外,我还要指出有一个特定的非空函数:

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

but it doesn't do exactly what you ask for.但它并不完全符合您的要求。 (Though it will work in most situations). (虽然它在大多数情况下都有效)。

Not-empty returns nil if the collection is empty, and the collection itself if the collection is not empty.如果集合为空,非空返回 nil,如果集合不为空,则返回集合本身。 For predicate tests, that will function well.对于谓词测试,这将运行良好。 If you actually need true and false values, then (not (empty? x)) is what you're after.如果您确实需要 true 和 false 值,那么 (not (empty? x)) 就是您所追求的。

If you need a boolean, I think (comp not seq) has a nice ring to it.如果你需要一个布尔值,我认为(comp not seq)有一个很好的戒指。

Example usage:用法示例:

((comp not seq) coll)

And if you need to store it as a fn for later:如果您需要将其存储为 fn 以供以后使用:

(def not-empty' (comp not seq))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM