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?

War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top