返回第一个非空/空值?

时间:2013-09-06 18:43:12

标签: clojure

我有2个绑定我正在调用路径和回调。

我要做的是返回第一个非空的。在javascript中它看起来像这样:

var final = path || callback || "";

我如何在clojure中这样做?

我正在查看“某些”功能,但我无法弄清楚如何将compjure.string / blank检查结合起来。我目前将此作为测试,但不起作用。在这种情况下,它应该返回nil我认为。

(some (clojure.string/blank?) ["1" "2" "3"])

在这种情况下,它应该返回2

(some (clojure.string/blank?) ["" "2" "3"])

5 个答案:

答案 0 :(得分:7)

(first (filter (complement clojure.string/blank?) ["" "a" "b"]))

修改:正如评论中所指出的,(filter (complement p) ...)可以改写为(remove p ...)

(first (remove clojure.string/blank? ["" "a" "b"]))

答案 1 :(得分:2)

这是您使用some函数的方式:

(some #(when-not (empty? %) %) ["" "foo" ""])
"foo"
(some #(when-not (empty? %) %) ["bar" "foo" ""])
"bar"

正如其他人所指出的,filter是另一种选择:

(first (filter #(not (empty? %)) ["" "" "foo"])
"foo"

第三种选择是使用递归:

(defn first-non-empty [& x]
  (let [[y & z] x]
    (if (not (empty? y))
      y
      (when z (recur z)))))

(first-non-empty "" "bar" "")
"bar"
(first-non-empty "" "" "foo")
"foo"
(first-non-empty "" "" "")
nil

我使用empty?代替blank?来节省输入,但唯一的区别应该是如何处理空格。

答案 2 :(得分:2)

如果你想要一个序列的第一个非空白字符串,你可以使用这样的东西:

(first (filter #(not (clojure.string/blank? %)) ["" "2" "3"]))

这将返回2

我不明白的是你使用某个函数的第一个例子,你说它应该返回nil但是第一个非空字符串是“1”。

答案 3 :(得分:2)

如果你很幸运拥有由nil和/或false表示的“空值”,你可以使用:

(or nil false "a" "b")

哪会返回"a"

与您的JavaScript示例相同的是:

(let [final (or path callback "")]
  (println final))

答案 4 :(得分:1)

我很难准确地说出你想要的东西,所以这是我对你要做的事情的理解。

在我的情况下,我想查找第二份报告中是否缺少一份报告中的项目。匹配返回nil,不匹配返回不匹配的实际项目。

以下函数最终将映射值的值与键进行比较。

使用像find-first这样的东西可能就是你想做的事。

(defn find-first 
  "This is a helper function that uses filter, a comparision value, and
   stops comparing once the first match is found. The actual match
   is returned, and nil is returned if comparision value is not matched."
  [pred col]
  (first (filter pred col)))

(defn str-cmp
 "Takes two strings and compares them. Returns 0 if a match; and nil if not."
 [str-1 str-2 cmp-start-pos substr-len]

 (let [computed-str-len (ret-lowest-str-len str-1 str-2 substr-len)
  rc-1 (subs str-1 cmp-start-pos computed-str-len)
  rc-2 (subs str-2 cmp-start-pos computed-str-len)]

  (if (= 0 (compare rc-1 rc-2))
   0
   nil)))

(defn cmp-one-val
"Return nil if first key match found, 
 else the original comparision row is returned.
 cmp-row is a single sequence of data from a map. i
 cmp-key is the key to extract the comparision value.
 cmp-seq-vals contain a sequence derived from 
 one key in a sequence of maps.
 cmp-start and substr-len are start and stop 
 comparision indicies for str-cmp."

 [cmp-row cmp-key cmp-seq-vals cmp-start substr-len]
 (if (find-first #(str-cmp (cmp-key cmp-row) %1 cmp-start substr-len) cmp-seq-vals)
  nil
  cmp-row))