Clojure中Vector和List的区别及其相关函数

本文详细探讨了Clojure中Vector和List的特点,包括它们的存储结构、插入和查找效率。Vector适合大量查找操作,而List在前端插入更高效。常用创建函数如vector和list,插入函数如conj和cons,删除函数如pop和subvec,获取元素的函数如nth和get等。此外,还介绍了如何判断序列类型以及函数效率问题。
摘要由CSDN通过智能技术生成

  Clojure是一门动态类型的语言,运行时才会做类型检查。它也不会像java这种面向对象编程语言,在调用一个对象的函数时,首先这个函数必须是属于该对象的函数,否则检查报错。所以对于clojure中的数据类型为Vector或者List的变量,总是会让初学者在选择时比较发愁,不知道什么情况下使用vector好?什么情况下使用list好?哪些函数是接收list作为参数的?而哪些函数又是接收vector作为参数的?它们的区别又是什么?本博客关于近期对clojure的list和vector的学习做一个总结:

1.List与Vector的特点:

  Clojure中既有列表(list),也有向量(vector),两者都是序列数据结构,它们的特点对比如下:

  • 存储类型:
    list是链式存储结构,而vector是顺序存储类型
  • 数据插入:
    list支持高效的前端插入,而vector在尾端插入会更高效
  • 数据查找:
    在数据查找方面,因为存储类型的不同,vector的时间复杂度会明显低于list,因为vector采取的理想b树的存储结构(http://blog.csdn.net/zdplife/article/details/52138512),所以其查找效率接近常数时间(O(log32n)),而list的查找操作需要O(N)的时间复杂度,所以在存在大量查找操作时,尽量选择vector。

2.创建相关函数:

  • vector的相关创建函数:
;;方法1:直接使用字面值常量表示法
[1 2 3]
;;=> [1 2 3]

;;方法2:使用vector,接收n个元素
(vector 1 2 3)
;;=> [1 2 3]

;;方法3:在已有结构的基础上创建向量
(vec '(1 2 3))
;;=> [1 2 3]
;;map中的元素转换为序列时,是以键值对的形式作为元素返回的
(vec {
    :a 1 :b 2})
;;=> [[:a 1] [:b 2]]

;;方法4:使用into函数在已有结构基础上创建向量
(into [] {
    :a 1 :b 2})
;;=> [[:a 1] [:b 2]]
(into []  '(1 2 3))
;;=> [1 2 3]

  以上是vector四个创建函数,经常用到的是最后两个,我在博客(http://blog.csdn.net/zdplife/article/details/52138512)中讲到,因为into使用了transient(瞬态存储结构),所以其效率会vec函数快30%,vec的可读性比较强,而into函数的效率更大,所以在使用时可以折中选择。
  还有就是map被转换为序列时,是按照键值对返回的,这个在写代码时需要注意。

  • list的相关创建函数:
    list的创建函数与vector的类似,如下:
;;由于()在clojue中会被当作函数操作符,所以这里在用字面值常量创建列表时,需要加单引号,阻止求求值
'(1 2 3)
;;=> (1 2 3)

;;该list与vector的用法类似
(list 1 2 3)
;;=> (1 2 3)

;;该into用法与上述介绍的一致
(into '() [1 2 3])
;;=> (3 2 1)

  into在效率上依然是首要的选择,而使用单引号创建list时,有一点缺点就是它不会解释里面的变量或者函数调用,所以这种方法要尽量少用:

(def a 4)
;;=> #'insight.main/a
;;单引号会阻止对a求值,返回字面值
'(1 2 a)
;;=> (1 2 a)

;;而list函数则会对a进行解析,所以尽量选择list函数
(list 1 2 a)
;;=> (1 2 4)

  其中在使用into函数时,vector和list中元素的序列是不一样的,这是因为into函数会以此调用conj函数将后者的元素一个一个加入到前面的序列中,但由于这两个存储

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值