Gibt es eine ähnliche Funktion wie „andmap“ in Clojure?
-
06-07-2019 - |
Frage
Ich möchte eine Reihe von Tests auf meiner Liste anwenden und sicherstellen, dass alle Tests bestanden sind. Gibt es eine ähnliche Funktion wie "andmap" in Clojure?
Lösung
Sie könnten every?
verwenden:
user=> (every? string? '("hi" 1))
false
Hier ist die Dokumentation auf every?
.
Andere Tipps
Clojure 1.3 wird jede-pred hinzufügen (und die some-fn für das "oder" Version verwandt).
clojure.core / every-pred ([P] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps])
nimmt einen Satz von Prädikaten und gibt eine Funktion f, die true zurückgibt, wenn alle ihre Komponieren Prädikate geben einen logischen wahren Wert gegen alle seine Argumente, sonst kehrt falsch. dass f Hinweis ist Kurzschluss, dass er die Ausführung auf dem ersten stoppen Argument, das ein logisches falsches Ergebnis gegen die ursprünglichen Prädikate auslöst.
Eine naive Implementierung könnte sein:
(defn alle-pred [& preds] (fn [& args] (jeder? # (Alle?% Args) preds)))
aber die tatsächliche Umsetzung wird eine bessere Leistung haben.
Ich schrieb andmap
als Makro, das Prädikate als Argumente und baut eine Funktion, dass „wickelt eine and
um die Prädikate“, das heißt nimmt.
(andmap integer? odd?)
==>
(fn [x] (and (integer? x)
(odd? x)))
(es dehnt nicht zu genau das, aber es dehnt sich etwas Gleichwertiges zu diesem)
Dies hat den Vorteil, dass es auf den Prädikaten shortcuircuts so können Sie schreiben
(every? (andmap integer? odd?) [1 3 "a string"])
ohne eine Laufzeitausnahme zu bekommen, wie Sie mit Arthurs beantworten .
Hier ist die Definition von andmap
:
(defmacro andmap ([] `(fn [& x#] true)) ([p & ps] `(fn [& x#] (and (apply ~p x#) (apply (andmap ~@ps) x#)))))
Es ist auch möglich andmap
als Funktion, die auch Kurzschlüsse auf seine Prädikate aufgrund lazyness zu definieren:
(defn andmap [& ps] (fn [& x] (every? true? (map (fn [p] (apply p x)) ps))))
Die Prädikate andmap kann eine beliebige Anzahl von Argumenten entgegennehmen, so ist es möglich, schreiben
(map (andmap #(and (integer? %1)
(integer? %2))
#(and (odd? %1)
(even? %2))
<)
[1 3 9]
[2 6 "string"])
, die ausgewertet (true true false)
.
every?
wird fragen: „Hat diese eine Funktion return true für jedes Mitglied der seq“, die zu nah ist, was ich glaube, Sie fragen nach. Eine Verbesserung every?
würde eine Liste von Funktionen übernehmen und fragen, „all diese Prädikate für jedes Mitglied dieser seq wahr sind“.
Hier ist ein erster Versuch:
(defn andmap? [data tests]
(every? true? (for [d data, f tests]
(f d))))
user> (andmap? '(2 4 8) [even? pos?])
true
user> (andmap? '(2 4 8) [even? odd?])
false