8

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

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

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

我如何在clojure中做到这一点?

我正在查看“some”函数,但我不知道如何在其中组合 compjure.string/blank 检查。我目前有这个作为测试,它不起作用。在这种情况下,我认为它应该返回 nil 。

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

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

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

5 回答 5

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

编辑:正如评论中指出的,(filter (complement p) ...)可以重写为(remove p ...)

(first (remove clojure.string/blank? ["" "a" "b"]))
于 2013-09-06T19:07:23.443 回答
3

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

(or nil false "2" "3")

哪个会返回"2"

等效于您的 JavaScript 示例将是:

(let [final (or path callback "")]
  (println final))
于 2014-02-24T10:38:09.600 回答
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?节省打字,但唯一的区别应该是如何处理空格。

于 2013-09-06T19:06:41.423 回答
2

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

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

这将返回 2

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

于 2013-09-06T19:07:20.363 回答
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))
于 2013-09-06T18:52:28.373 回答