41 votes

Clojure: convertir les chaînes de clés de hachage-cartes en mots clés?

Je suis de l'extraction de données à partir de Redis à l'aide de Aleph:

(apply hash-map @(@r [:hgetall (key-medication id)]))

Le problème est que ces données revient avec chaînes par touches, par ex:

({"name" "Tylenol", "how" "instructions"})

Quand j'en ai besoin pour être:

({:nom de "Tylenol", :comment "instructions})

J'ai déjà la création d'une nouvelle carte via:

{ :nom (m "nom"), :comment (m "comment")}

Mais c'est inefficace, pour un grand nombre de touches.

Si il y a une fonction qui fait cela? Ou dois-je en boucle sur chaque?

94voto

djhworld Points 2703

Vous pouvez également utiliser la bibliothèque clojure.walk pour obtenir le résultat souhaité avec la fonction keywordize-keys

 (use 'clojure.walk)
(keywordize-keys {"name" "Tylenol", "how" "instructions"})
;=> {:name "Tylenol", :how "instructions"}
 

Cela parcourra également la carte de manière récursive, ce qui permettra de "classer par mot-clé" les clés de la carte imbriquée également.

http://clojuredocs.org/clojure_core/clojure.walk/keywordize-keys

47voto

mikera Points 63056

Il existe une fonction pratique appelée mot - clé qui convertit les chaînes en mots clés appropriés:

 (keyword "foo")
=> :foo
 

Il s'agit donc simplement de transformer toutes les clés de votre carte à l'aide de cette fonction.

J'utiliserais probablement une compréhension de liste avec déstructuration pour ce faire, quelque chose comme:

 (into {} 
  (for [[k v] my-map] 
    [(keyword k) v]))
 

9voto

Matt W-D Points 574

Je suis d'accord avec djhworld, clojure.walk/keywordize-keys est ce que vous voulez.

Il vaut la peine de jeter un œil au code source de clojure.walk/keywordize-keys :

 (defn keywordize-keys
  "Recursively transforms all map keys from strings to keywords."
  [m]
  (let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
    (clojure.walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
 

La transformation inverse est parfois pratique pour Java Interop:

 (defn stringify-keys
  "Recursively transforms all map keys from keywords to strings."
  [m]
  (let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
    (clojure.walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
 

6voto

viebel Points 1990

Vous pouvez y parvenir de manière très élégante en utilisant zipmap :

 (defn modify-keys [f m] (zipmap (map f (keys m)) (vals m)))
(modify-keys keyword {"name" "Tylenol", "how" "instructions"})
; {:how "instructions", :name "Tylenol"}
 

Fondamentalement, zipmap permet de créer une carte en spécifiant les clés et les valeurs séparément.

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