143 votes

Mapper une fonction sur les valeurs d'une carte dans Clojure

Je veux transformer une carte de valeurs en une autre carte avec les mêmes clés mais avec une fonction appliquée aux valeurs. Je pense qu'il y avait une fonction pour faire cela dans l'api clojure, mais j'ai été incapable de le trouver.

Voici un exemple d'implémentation de ce que je recherche

 (defn map-function-on-map-vals [m f]
  (reduce (fn [altered-map [k v]] (assoc altered-map k (f v))) {} m))
(println (map-function-on-map-vals {:a "test" :b "testing"} #(.toUpperCase %)))
{:b TESTING, :a TEST}
 

Est-ce que quelqu'un sait si map-function-on-map-vals existe déjà? Je pense que oui (probablement avec un nom plus agréable).

169voto

Brian Carper Points 40078

J'aime bien votre version reduce . Je pense que c'est idiomatique. Voici une version utilisant la compréhension de la liste de toute façon.

 (defn foo [m f]
  (into {} (for [[k v] m] [k (f v)])))
 

98voto

Arthur Edelstein Points 932

Vous pouvez utiliser la fonction fmap à partir de clojure.contrib.generic.functor :

 user=> (use '[clojure.contrib.generic.functor :only (fmap)])
nil
user=> (fmap inc {:a 1 :b 3 :c 5})
{:a 2, :b 4, :c 6}
 

41voto

Arthur Ulfeldt Points 45059

Voici un moyen assez typique de transformer une carte. zipmap prend une liste de clés et une liste de valeurs et "fait la bonne chose" en produisant une nouvelle carte Clojure. Vous pouvez également placer les map autour des touches pour les modifier ou les deux.

 (zipmap (keys data) (map #(do-stuff %)) (vals data))
 

ou pour envelopper dans votre fonction:

 (defn map-function-on-map-vals [m f]
    (zipmap (keys m) (map f (vals m)))
 

8voto

Siddhartha Reddy Points 3555

Voici un moyen assez idiomatique de le faire:

 (defn map-function-on-map-vals [m f]
        (apply merge
               (map (fn [[k v]] {k (f v)})
                    m)))
 

Exemple:

 user> (map-function-on-map-vals {1 1, 2 2, 3 3} inc))
{3 4, 2 3, 1 2}
 

2voto

Carl Smotricz Points 36400

Je suis un Clojure n00b, donc il peut y avoir beaucoup plus de solutions élégantes. Voici la mienne:

(def example {:a 1 :b 2 :c 3 :d 4})
(def func #(* % %))

(prn example)

(defn remap [m f]
  (apply hash-map (mapcat #(list % (f (% m))) (keys m))))

(prn (remap example func))

Le anon func fait un peu 2-liste de chaque clé et sa f ed valeur. Mapcat exécute cette fonction au cours de la séquence de la carte avec les touches et concatène l'ensemble des travaux dans une grande liste. "appliquer de hachage carte" crée une nouvelle carte à partir de cette séquence. L' (% m) peut sembler un peu étrange, il est idiomatiques Clojure pour l'application d'une clé à une carte de chercher la valeur associée.

Le plus fortement recommandé de lecture: Clojure Feuille de Triche .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X