制作非零条目列表

Ant*_*ald 4 clojure clojurescript

说我有这样的功能:

(defn my-f [a & [b]]
   (if (nil? b)
      (my-other-f a)
      (my-other-f a b)))
Run Code Online (Sandbox Code Playgroud)

这当然是一种简化。它是另一个函数的包装函数——实际上 a 是在这个函数内部处理的。如果可选参数 b 没有传递给 my-f,它也不应该传递给 my-other-f。

我正在考虑另一种方法来实现这一目标:

(defn my-f [a & [b]]
   (apply my-other-f (make-list-of-not-nil-entries a b)))
Run Code Online (Sandbox Code Playgroud)

是否有内置功能可以完成这项工作?


例子

有时,过于抽象会令人困惑,所以我在这里提供真实案例。以下 ClojureScript 代码有效,其目的显然是尝试不同的浏览器特定选项,以便从 HTML 画布元素获取“webgl”上下文。

(defn create-ctx [canvas & [options]]
  (some (if options
          #(.getContext canvas % (clj->js options))
          #(.getContext canvas %))
        ["webgl" "experimental-webgl" "webkit-3d" "moz-webgl"]))
Run Code Online (Sandbox Code Playgroud)

给定的 Canvas 元素的方法 getContext 实际上等待一个参数,以及另一个可选的参数。上述包装函数具有相同的数量。

我只是想看看,是否有一种快速的方法来避免 1 和 2 arity 函数调用的显式切换。

Pio*_*dyl 5

我认为您的第一个解决方案在其意图上更具可读性和明确性。它的性能也比带有apply.

如果您仍然想使用apply,则使用的最短解决方案clojure.core是:

(remove nil? [a b]) 
Run Code Online (Sandbox Code Playgroud)

或者

(keep identity [a b]) 
Run Code Online (Sandbox Code Playgroud)

或者

(filter some? [a b]) 
Run Code Online (Sandbox Code Playgroud)

我不知道有任何内置函数接受 varargs 并仅返回非 nil 元素的 seq。你可以创建一个:

(defn non-nils [& args] 
  (remove nil? args) 
Run Code Online (Sandbox Code Playgroud)

或使用ignoring-nilsflatland.useful.fn.