Existe-t-il une fonction similaire à & # 8220; andmap & # 8221; en clojure?

StackOverflow https://stackoverflow.com/questions/1209824

  •  06-07-2019
  •  | 
  •  

Question

Je souhaite appliquer une série de tests à ma liste et m'assurer que tous les tests sont réussis. Existe-t-il une fonction similaire à "andmap"? à Clojure?

Était-ce utile?

La solution

Vous pourriez utiliser chaque? :

user=> (every? string? '("hi" 1))
false

Voici la documentation sur le tous les? .

Autres conseils

Clojure 1.3 ajoutera every-pred (ainsi que le filtre associé pour la version "ou").

clojure.core / every-pred ([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps])

Prend un ensemble de prédicats et retourne une fonction f qui retourne vrai si tous ses   les prédicats de composition renvoient une valeur logique vraie pour tous ses arguments, sinon il retourne   faux. Notez que f est en court-circuit en ce sens qu’il arrête l’exécution le premier jour.   argument qui déclenche un faux résultat logique par rapport aux prédicats d'origine.

Une implémentation naïve pourrait être:

(defn every-pred [& amp preds] (fn [& ampgs; args]] (chaque? # (chaque?% args) preds))))

mais la mise en œuvre réelle aura de meilleures performances.

J'ai écrit andmap en tant que macro qui prend des prédicats comme arguments et crée une fonction qui "encapsule un et autour des prédicats", c'est-à-dire,

.
(andmap integer? odd?) 
==>
(fn [x] (and (integer? x)
             (odd? x)))

(cela ne s'étend pas à exactement ceci, mais à quelque chose d'équivalent à cela)

Ceci a l’avantage de pouvoir effectuer des raccourcis sur les prédicats afin que vous puissiez écrire

(every? (andmap integer? odd?) [1 3 "a string"])

sans obtenir une exception d'exécution identique à celle que vous obtiendriez avec Réponse d'Arthurs .

Voici la définition de andmap :

(defmacro andmap 
  ([]       `(fn [& x#] true))
  ([p & ps] `(fn [& x#] (and (apply ~p x#)
                             (apply (andmap ~@ps) x#)))))

Il est également possible de définir andmap en tant que fonction qui court-circuite également sur ses prédicats en raison de la paresse:

(defn andmap [& ps]
  (fn [& x]
    (every? true? (map (fn [p] (apply p x)) ps))))

Les prédicats de andmap peuvent prendre un nombre arbitraire d'arguments, il est donc possible d'écrire

(map (andmap #(and (integer? %1)
                   (integer? %2))
             #(and (odd? %1)
                   (even? %2))
             <)
     [1 3 9]
     [2 6 "string"])

qui correspond à (true true false) .

every? demandera "Est-ce que cette fonction est vraie pour chaque membre du seq", ce qui est proche de ce que je pense que vous demandez. Une amélioration de chaque? prendrait une liste de fonctions et demanderait "Tous ces prédicats sont-ils vrais pour chaque membre de cette séquence".

Voici une première tentative:

(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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top