Skip to content

Instantly share code, notes, and snippets.

@krishnabhargav
Last active August 29, 2015 14:04
Show Gist options
  • Save krishnabhargav/3bfb4ceb79fbc6e68864 to your computer and use it in GitHub Desktop.
Save krishnabhargav/3bfb4ceb79fbc6e68864 to your computer and use it in GitHub Desktop.
Clojure Destructuring
;; Positional Destructuring
(def fullname ["Krishna", "Bhargava", "Vangapandu"])
(defn firstName [fullname]
; this is positional destructuring - works only on vectors as they are aligned sequentially
(let [[fName _ _] fullname]
fName))
(defn first5
"returns a vector with the first item as count of the sequence passed. The rest of the items are the first 5 items in the sequence."
[items]
;; items will be bound to "all"
;; "rest" is a seq not a vector
(let [[a1 a2 a3 a4 a5 &rest :as all] items]
[(count all) a1 a2 a3 a4 a5]))
(first5 (range 10)) ;; returns [10 0 1 2 3 4]
(first5 (range 2)) ;; returns [2 0 1 nil nil nil]
;;even this is allowed
(defn get-head [[head-item &more]]
head-item)
;; deep nested destructuring is also supported
(defn nested [[[a [b c]]]] ; [[]] [[ [a [b c]] ]]
[a c])
(nested [1 [2 3]]) ;returns [1 3]
;; Destructing in Maps
(def person {:first "Krishna" :last "Vangapandu" :middle "Bhargava" })
(def get-first-name [person]
;; [{variable key}] -> variable will be available in the let scope.
(let [{first-name :first} person]
first-name))
;; you can even do this
(def get-first-name2 [{first-name :first}]
first-name)
;;destructuring works for string keys as well
(def get-first-name3 [{first-name "f-name"}]
first-name)
(get-first-name3 {"f-name" "Krishna"})
;;destructuring using keys
(defn get-name-vector [{:keys [first-name last-name]}]
[first-name last-name])
(get-name-vector {:first-name "Krishna" :l-name "Vangapandu"}) ;; returns ["Krishna" nil] because :last-name isn't available
;;destructuring using :syms
(defn get-from-syms [{:syms [s1 s2]}] [s1 s2])
(get-from-syms {'s1 "s1" 's2 "s2"}) ;; returns ["s1" "s2"]
;;destructuring using :strs
(defn get-from-strs [{:strs [str1 str2]}] [str1 str2])
(get-from-strs {"str1" "String 1" "str2" :str2}) ;; returns ["String 1" :str2]
;;you can get the whole map using :as
(defn from-syms [{:syms [s1] :as input}] (str s1 input))
;;using :or to specify missing values
(defn missing-values [{:keys [s1 s2] :or {s1 "S1"}}] s1)
(missing-values {}) ;; returns "S1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment