在clojure中,哈希表是最通用的一种Map,和java中的HashMap同样,它们在处理大量数据方面效率很是高,可是不保证顺序。咱们可使用函数hash-map来建立哈希表: java
=>(hash-map :truck "Toyota" :car "Subaru" :plane "de Havilland") {:plane "de Havilland", :truck "Toyota", :car "Subaru"} =>(class (hash-map :truck "Toyota" :car "Subaru" :plane "de Havilland")) clojure.lang.PersistentHashMap
在clojure中,全部的类型对象均可以做为map的键,甚至是函数对象也能够。可是咱们推荐使用关键字类型(以冒号开头)做为map的键,由于关键字做为键时哈希表性能最好。建立哈希表时不必定非得用hash-map 函数,下面就是一个更简便的方式: 编程
;;直接使用{}来建立哈希表 =>{:truck "Toyota" :car "Subaru" :plane "de Havilland"} {:truck "Toyota", :car "Subaru", :plane "de Havilland"}不过,用上面这种方式,若是传入的键值对少于9个,它实际上建立的是ArrayMap而不是HashMap:
=>(class {:truck "Toyota" :car "Subaru" :plane "de Havilland"}) clojure.lang.PersistentArrayMap一旦你把它绑定到一个变量上,它自动就转换成了hashMap:
=> (def map {test: 1}) #'user/map => (class map) clojure.lang.PersistentHashMap
ArrayMap 和 HashMap这种转换,看起来很诡异。可是不要担忧,由于大部分状况下,这都不会引发问题。我见过的全部函数对这两种map的操做都是同样的,没有任何区别。 json
建立map时,若是你想让键值对之间的分隔更清晰,可使用逗号分隔符: 函数式编程
;;使用hash-map函数 => (hash-map :key1 1 , :key2 2) {:key2 2, :key1 1} ;;直接建立 =>{:key1 1 , :key2 2} {:key2 2, :key1 1}
咱们再来看看和map相关的操做 函数
;;若是是map的键是关键字类型,关键字直接能够当作函数使用 => (def m {:key1 1, :key2 2}) {:key1 1, :key2 2} ;;获取:key1对应的值 => (:key1 m) 1 ;;map自己也能够用于取值,这种适应于任意类型的key => (m :key1) 1
一种更好的方式是使用get函数,由于能够设置缺省值。(get 也能够用于向量,把key变成索引值便可) 性能
=> (def m {:key1 1 :key2 :2}) ;;获取 :key1对应的值 => (get m :key1) 1 ;;若是 :key3不存在,返回缺省值 => (get m :key3 "default") "default"
咱们可使用get-in 获取嵌套map的值 spa
;;建立嵌套map user=> (def m {:username "sally" :profile {:name "Sally Clojurian" :address {:city "Austin" :state "TX"}}})
'user/m user=> (get-in m [:profile :name]) "Sally Clojurian" user=> (get-in m [:profile :address :city]) "Austin" user=> (get-in m [:profile :address :zip-code]) nil ;;若是键不存在,能够设置默认值 user=> (get-in m [:profile :address :zip-code] "no zip code!") "no zip code!"
我敢说这是json好么!!!(get-in 函数可不仅是用于map,向量也可使用get-in操做) code
;;没则增长,有则修改 =>(conj {:name "qh" :age 20} {:age 30} {:gender 'male}) {:gender mail, :age 30, :name "qh"} ;;没则增长,有则修改 =>(merge {:name "qh" :age 20} {:age 30} {:gender 'male}) {:gender mail, :age 30, :name "qh"} ;;assoc是操做map和对应的元素,上面两个操做的是多个map,注意区别 =>(assoc {:name "qh" :age 20} :age 30 :gender 'male) {:gender mail, :age 30, :name "qh"}
;;删除:name对应的键值对 =>(dissoc {:name "qh" :age 30} :name) {:age 30} ;;给m绑定一个map => (def m {:name "qh" :age 30}) #'user/m ;;执行删除操做 =>(dissoc m :name) {:age 30} ;;m没有变化 =>m {:name "qh" :age 30}咱们的删除操做只是返回一个新的map,并不会对原有的map形成影响。这点要注意。这也是函数式编程中强调的"消除反作用"。以前的添加和修改都是如此。
;;使用keys函数 => (keys {:name "clo" :age 30}) (:name :age)
;;使用vals函数获取全部value => (vals {:name "clo" , :age 30}) ("clo" 30)
若是咱们想要建立一个有序的map(按照key的天然顺序),可使用sorted-map函数来建立一个有序map。 对象
user=> (def sm (sorted-map :c 1 :b 2 :f 3 :a 3)) #'user/sm user=> sm {:a 3, :b 2, :c 1, :f 3}有序map增删改查操做和上面同样。