2016-04-14 3 views
2

sagen, dass ich eine Funktion wie dieses:Make Liste der nicht-Null-Einträge

(defn my-f [a & [b]] 
    (if (nil? b) 
     (my-other-f a) 
     (my-other-f a b))) 

Dies ist natürlich eine Vereinfachung ist. Es ist eine Wrapper-Funktion für eine andere Funktion - und in Wirklichkeit wird ein a innerhalb dieser Funktion verarbeitet. Wenn das optionale Argument b nicht an my-f übergeben wird, sollte es auch nicht an my-other-f übergeben werden.

ich eine andere Art und Weise dachte, dies zu erreichen:

(defn my-f [a & [b]] 
    (apply my-other-f (make-list-of-not-nil-entries a b))) 

Gibt es vielleicht eine eingebaute Funktion um diesen Job zu tun?


Beispiel

Manchmal ist zu abstrakt ist verwirrend, also bin ich hier, um die realen Fall bereitstellt. Der folgende ClojureScript-Code funktioniert, sein Zweck ist offensichtlich, verschiedene browserspezifische Optionen auszuprobieren, um einen "Webgl" -Kontext von einem HTML-Canvas-Element zu erhalten.

Die Methode getContext des angegebenen Canvas-Elements erwartet eigentlich ein Argument und ein anderes, das optional ist. Die obigen Wrapper-Funktionen haben die gleiche Arity.

Ich wollte nur sehen, ob es einen schnellen Weg gibt, den expliziten Schalter für den 1 und 2 Arity Funktionsaufruf zu vermeiden.

+2

Ist es eine Option, verschiedene Aritäten für 'my-f' zu verwenden? '(defn my-f ([a] (meine-andere-f a)) ([a b] (meine-andere-f a b)))'. Das sieht wirklich nach einem Designproblem aus. Zum Beispiel, wenn Sie 3 Argumente fn: '(defn my-f [abc])' mit optionalen 'b' und' c' und 'b == nil' haben, würde Ihre Vorgehensweise beim Entfernen von Nils" c "an der richtigen Stelle übergeben von 'b' ..' (my-f 1 nil 100) '.. – leetwinski

Antwort

3

Ich würde argumentieren, dass Ihre erste Lösung viel lesbarer und expliziter über ihre Absicht ist. Es wird auch viel bessere Leistung als die mit apply haben.

Wenn Sie noch mit apply gehen wollen, die kürzeste Lösung clojure.core Verwendung wäre:

(remove nil? [a b]) 

Oder

(keep identity [a b]) 

Oder

(filter some? [a b]) 

Ich bin nicht bekannt, dass eingebaute Funktion, die varargs übernimmt und eine Folge von nur Nicht-Null-Elementen zurückgibt s.

(defn non-nils [& args] 
    (remove nil? args) 

Oder verwenden ignoring-nils von flatland.useful.fn: Sie könnten erstellen.

+0

vielen Dank für die Überlegungen. –