-
-
Save thheller/7ddc0371561deaf13e11 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns util.camelize-dasherize | |
(:import (clojure.lang IPersistentMap Keyword)) | |
(:require [clojure.string :as s] | |
[clojure.zip :as zip])) | |
; TODO: regex is slow, should try iterating the string. | |
(defn dasherize-string* | |
"Converts an underscored or camelized string | |
into an dasherized one." | |
[s] | |
(when s | |
(-> s | |
(s/replace #"([A-Z][a-z]+)" (fn [[match c]] | |
(if c (str "-" (s/lower-case c)) ""))) | |
(s/replace #"([A-Z]+)" "-$1") | |
(s/replace #"[-_\s]+" "-") | |
(s/replace #"^-" "")))) | |
(def dasherize-string (memoize dasherize-string*)) | |
(defn camelize-string* | |
"Converts a string from dash-case to camelCase." | |
[^String s] | |
(when s | |
(some-> s | |
(s/replace #"[-_\s]+(.)?" | |
(fn [[match c]] | |
(if c (s/upper-case c) "")))))) | |
(def camelize-string (memoize camelize-string*)) | |
(defn dasherize-keyword* | |
[k] | |
(when k | |
(keyword (dasherize-string (name k))))) | |
(def dasherize-keyword (memoize dasherize-keyword*)) | |
(time (dotimes [x 400000] (dasherize-keyword :clientOSVersion))) | |
;"Elapsed time: 915.063554 msecs" | |
(defn camelize-keyword* | |
[k] | |
(when k | |
(keyword (camelize-string (name k))))) | |
(def camelize-keyword (memoize camelize-keyword*)) | |
(time (dotimes [x 400000] (camelize-keyword :client-OS-version))) | |
;"Elapsed time: 537.186386 msecs" | |
(defn camelize-map-1 [m] | |
(into {} (map (fn [[k v]] | |
[(camelize-keyword k) v]) m))) | |
(defn dasherize-map-1 [m] | |
(into {} (map (fn [[k v]] | |
[(dasherize-keyword k) v]) m))) | |
(defn camelize-map-recur [m] | |
(into {} (map (fn [[k v]] | |
[(camelize-keyword k) (if (map? v) (camelize-map-recur v) v)]) m))) | |
(defn dasherize-map-recur [m] | |
(into {} (map (fn [[k v]] | |
[(dasherize-keyword k) (if (map? v) (dasherize-map-recur v) v)]) m))) | |
(defn map-zipper [m] | |
(zip/zipper | |
(fn [x] (or (map? x) (map? (nth x 1)))) | |
(fn [x] (seq (if (map? x) x (nth x 1)))) | |
(fn [x children] | |
(if (map? x) | |
(into {} children) | |
(assoc x 1 (into {} children)))) | |
m)) | |
(defn edit-map-keys-zip [m f] | |
(loop [loc (map-zipper m)] | |
(if (zip/end? loc) | |
(zip/root loc) | |
(recur (zip/next | |
(if (vector? (zip/node loc)) | |
(zip/edit loc #(do [(f (first %)) (second %)])) | |
loc)))))) | |
(defn camelize-map-zip [m] | |
(edit-map-keys-zip m camelize-keyword)) | |
(defn dasherize-map-zip [m] | |
(edit-map-keys-zip m dasherize-keyword)) | |
(defprotocol ICamelizable | |
(camelize [this])) | |
(defprotocol IDasherizable | |
(dasherize [this])) | |
(extend-protocol ICamelizable | |
String | |
(camelize [this] | |
(camelize-string this)) | |
Keyword | |
(camelize [this] | |
(camelize-keyword this)) | |
IPersistentMap | |
(camelize [this] | |
(camelize-map-zip this))) | |
(extend-protocol IDasherizable | |
String | |
(dasherize [this] | |
(dasherize-string this)) | |
Keyword | |
(dasherize [this] | |
(dasherize-keyword this)) | |
IPersistentMap | |
(dasherize [this] | |
(dasherize-map-zip this))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment