文档章节

clojure 新手指南(14):Hash-Maps ,Array-Maps & Sorted...

凯奥斯
 凯奥斯
发布于 2013/07/18 11:24
字数 996
阅读 774
收藏 2

hash-map

创建

在clojure中,哈希表是最通用的一种Map,和java中的HashMap一样,它们在处理大量数据方面效率非常高,但是不保证顺序。我们可以使用函数hash-map来创建哈希表:

=>(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的操作都是一样的,没有任何区别。

创建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的值

;;创建嵌套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操作)


增加/修改

;;没则增加,有则修改 
=>(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造成影响。这点要注意。这也是函数式编程中强调的"消除副作用"。之前的添加和修改都是如此。


获取所有的key

;;使用keys函数
=> (keys {:name "clo" :age 30})
(:name :age)


获取所有的value

;;使用vals函数获取所有value
=> (vals {:name "clo" , :age 30})
("clo" 30)


Sorted Maps

如果我们想要创建一个有序的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增删改查操作和上面一样。


© 著作权归作者所有

凯奥斯
粉丝 44
博文 51
码字总数 41388
作品 0
朝阳
程序员
私信 提问
Understanding Redis hash-max-ziplist-entries

Understanding Redis hash-max-ziplist-entries Peterbe.com2018-01-081 阅读 redismaxhashentries This is an advanced topic for people who do serious stuff in Redis. I need to do ser......

Peterbe.com
2018/01/08
0
0
Clojure 1.6 正式版发布,并发编程语言

Clojure 1.6 正式版发布,此版本更新内容如下: 1 兼容性和依赖关系 1.1 JDK 版本更新 Clojure now builds with Java SE 1.6 and emits bytecode requiring Java SE 1.6 instead of Java SE ......

oschina
2014/03/26
3.5K
18
Top K Frequent Items Algorithm

Top K Frequent Items Algorithm Zhipeng Jiang2017-11-141 阅读 Top K frequent elements is a classic interview question that requires a basic understanding of HashMap and Heap. In ......

Zhipeng Jiang
2017/11/14
0
0
Java How to Program学习笔记_第十六章_Java集合(Generic Collections)——章节小结(Summary)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hpdlzu80100/article/details/84963920 自己选择的路,含着泪也要走完,继续学习Java! Summary Section 16.1 ...

预见未来to50
2018/12/12
0
0
postfix邮箱搭建之策略限制(笔记-2.20170809)

postfix 规则过滤: 标准响应代码: 5xx 永久性错误 4xx 暂时性错误 2xx 正确 2. 常用过滤规则类型: smtpdclientrestrictions#客户端过滤 smtpdhelorestrictions#helo指令过滤 smtpdsenderr...

想飞的剑鱼
2017/08/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS盒子模型

一、什么叫框模型 页面元素皆为框(盒子) 定义了元素框处理元素内容,内边距,外边距以及边框的计算方式 二、外边距 围绕在元素边框外的空白距离(元素与元素之间的距离) 语法:margin,定...

wytao1995
今天
4
0
Replugin借助“UI进程”来快速释放Dex

public static boolean preload(PluginInfo pi) { if (pi == null) { return false; } // 借助“UI进程”来快速释放Dex(见PluginFastInstallProviderProxy的说明) return PluginFastInsta......

Gemini-Lin
今天
4
0
Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
7
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部