Ce
{0 {:data {0 1, 3 4, 7 2}}, 1 {:data {0 0, 1 1, 2 3}}}
doit être trié comme ceci
{0 {:data {7 2, 0 1, 3 4}}, 1 {:data {2 3, 1 1, 0 0}}}
3 Réponses :
Vous pouvez utiliser une carte triée, par exemple
(sort-data {0 {:data {7 2, 0 1, 3 4}}, 1 {:data {2 3, 1 1, 0 0}}})
puis
(defn- sort-map [m] (into (sorted-map) m)) (defn sort-data [m] (->> m (map (fn [[k v]] [k (update v :data sort-map)])) (into {})))
J'ai une fonction unlazy
que j'utilise pour convertir des données en une forme canonique. Il parcourt récursivement n'importe quelle structure de données, convertissant tous les types séquentiels en vecteurs, et toutes les cartes / ensembles en versions triées. Il convertit également les types Java natifs en l'équivalent Clojure:
(ns demo.core (:require [clojure.walk :as walk])) (defn walk-sorted [coll] (let [sort-item (fn [item] (cond (map? item) (into (sorted-map) item) (set? item) (into (sorted-set) item) ] :else item)) ] (walk/prewalk sort-item coll))) ; or postwalk
Pour un cas simple, il pourrait être réduit comme suit:
(defn unlazy "Converts a lazy collection to a concrete (eager) collection of the same type." [coll] (let [unlazy-item (fn [item] (cond (sequential? item) (vec item) #?@(:clj [ (map? item) (into (sorted-map-generic) item) (set? item) (into (sorted-set-generic) item) ] :cljs [ (map? item) (into (sorted-map) item) ; #todo => (sorted-map-generic) (set? item) (into (sorted-set) item) ; #todo => (sorted-map-generic) ] ) #?@(:clj [ (instance? java.io.InputStream item) (slurp item) ; #todo need test (instance? java.util.List item) (vec item) ; #todo need test (instance? java.util.Map item) (into {} item) ; #todo need test (instance? java.lang.Iterable item) (into [] item) ; #todo need test ]) :else item)) result (walk/prewalk unlazy-item coll) ] result))
S'il vous plaît notez que les cartes / ensembles triés ne sont utiles que pour imprimer dans un bon format (pour faciliter la lecture). Sinon, cela n'affectera pas la façon dont votre programme s'exécute.
Pour des raisons avancées, vous souhaiterez peut-être explorer la clojure.data.avl
bibliothèque et la documentation de l'API .
voilà, je fais de nouveau la promotion de spectre ! (comme s'il avait besoin d'une promotion):
(require '[com.rpl.specter :refer [transform MAP-VALS]]) (transform [MAP-VALS :data] #(into (sorted-map) %) data) ;;=> {0 {:data {0 1, 3 4, 7 2}}, 1 {:data {0 0, 1 1, 2 3}}}
Bonne bibliothèque à première vue, j'ai besoin de la regarder plus en détail