clojure-基本语法-集合(一)

Clojure提供以下集合类型: list, vector, set, map。并且可以使用Java里面提供的集合类型。所有的clojure集合是不可修改的、异源的以及持久的。不可修改表示集合产生之后,不能从集合里面增加或删除元素。异源表示集合里面可以装任意类型的数据。持久的表示集合有更新时,更新之前的数据还在。CLojure以一种高效的,共享内存的方式来实现集合。
因为clojure里面的集合是不可修改的,所以也就没有对集合进行修改的函数。相反clojure里面提供了一些函数从一个已有的集合来高效地创建新的集合。同时也有一些函数操作一个已有的集合(比如vector)来产生另外一种类型的集合(比如LazySeq), 这些函数有不同的特性。
[b][color=red]一、列表List[/color][/b]
Clojure的List是单向链表,在头部增加新元素。List形式以“(1,2,3)”符号表示
创建list的方式:
1、通过list创建(这里list是clojure定义的指向clojure.lang.PersistentList的creator方法的符号)

user=> (list 1 2 3)
(1 2 3)
user=> (list "a" "b" "c")
("a" "b" "c")
user=> (list "a" 1 2.3 'a :keyname)
("a" 1 2.3 a :keyname)


2、通过list*创建
list*要求最后一个参数必须为集合

user=> (list* 1 [2 3])
(1 2 3)
user=> (list* nil [1 2])
(nil 1 2)
user=> (list* 1 nil)
(1)
user=> (list* 1 ())
(1)


3、通过其它方式创建:

user=> '(1 2 3);'符号阻止对后面的表达式立即求值,与quote意义相同
(1 2 3)
user=> (quote (1 2 3))
(1 2 3)
user=> (range 1 10)
(1 2 3 4 5 6 7 8 9)
user=> (repeat 5 1)
(1 1 1 1 1)


操作List的函数:
这里只介绍常用函数。
1、cons:
cons函数通过一个已有的集合来创建一个新的包含更多元素的集合,其中新加的元素在最前面

user=> (cons 1 (list 2 3 4 5))
(1 2 3 4 5)
user=> (cons (list 1 2) '(3 4 5))
((1 2) 3 4 5)


2、conj:
conj接收一个组合数据类型作为其第一个参数和任意数量的其它参数。并返回一个新的列表,这个列表将所有的其它参数连接到原来那个列表。conj函数也对Vector、Map、Set适用。

user=> (conj (list 1 2 3) 4);list在头部增加新元素,所以此处添加在起始位置
(4 1 2 3)
user=> (conj nil 2)
(2)
user=> (conj nil 2 3)
(3 2)


3、peek:
peek函数操纵一个单一的列表作为参数并返回列表中的第一个值

user=> (peek '(2 3 4))
2
user=> (peek (list nil "2" 3))
nil


4、pop:
pop函数操纵一个单一的列表作为参数并且返回一个去掉了首个元素的新列表

user=> (pop '(2 3 4))
(3 4)
user=> (pop (list nil "2" 3))
("2" 3)


5、first:
first返回列表第一个元素。在list中,first与peek效果相同,因为list是压栈操作元素

user=> (first nil)
nil
user=> (first ())
nil
user=> (first (list 1 2 3))
1


6、rest:
rest返回去除first之后剩下的集合

user=> (rest '(1 2 3))
(2 3)
user=> (rest nil)
()
user=> (rest ())
()

List是以单向链接列表的形式来实现的,在这一点上有利有弊。读取列表的第一个元素或者在列表头添加一个元素的操作都可以在常量时间内完成,然而访问列表的第N个元素却需要N次操作。

[b][color=red]二、向量Vector[/color][/b]
Vector支持高效地根据索引来访问元素,与数组类似。Vector形式以“[1,2,3]”符号表示
创建Vector方式:
1、vector:
vector接收任意数量的参数并将它们的值组成一个Vector

user=> (vector)
[]
user=> (vector nil)
[nil]
user=> (vector 1 2 3)
[1 2 3]
user=> (vector (list 1 2 3))
[(1 2 3)]


2、vec:
vec接收一个单独的参数,可能是任何Clojure或Java的数据类型,然后将其元素的值作为参数组成一个新的向量

user=> (vec (list 1 2 3))
[1 2 3]
user=> (vec [1 2 3])
[1 2 3]
user=> (vec '())
[]
user=> (vec nil)
[]


3、vector-of:
vector-of函数第一个参数指定Vector元素的类型,后面任意个参数作为元素,如果类型转换正确,则返回一个vector。vector-of第一个参数包括::int :long :float :double :byte :short :char or :boolean

user=> (vector-of :int 1 2 3)
[1 2 3]
user=> (vector-of :int "1" "2")
ClassCastException java.lang.String cannot be cast to java.lang.Character cloju
re.lang.RT.intCast (RT.java:1076)


常用操作函数:
1、conj:
conj函数在List常用函数中已介绍过,在操作Vector时,代码如下:

user=> (conj [1 2 3] [4])
[1 2 3 [4]]
user=> (conj [1 2 3] 4);由于vector在尾部增加新元素,所以4添加在末尾
[1 2 3 4]
user=> (conj '(1 2 3) 4);这里参数为list,由于list在头部增加新元素,所以4添加在1之前
(4 1 2 3)
user=> (conj ["a" 2 3.4] -1)
["a" 2 3.4 -1]
user=> (conj ["a" "b"] ["c"])
["a" "b" ["c"]]


2、peek:
peek返回vector中第一个值,与操作list的区别和conj一样

user=> (peek [1 2 3])
3
user=> (peek '(1 2 3))
1
user=> (peek [])
nil


3、pop:
pop返回peek之后剩下的集合

user=> (peek [1 2 3])
3
user=> (pop [1 2 3])
[1 2]
user=> (peek '(1 2 3))
1
user=> (pop '(1 2 3))
(2 3)


4、get:
get函数接收两个参数来操作vector。第一个参数是vector,第二个参数是一个整数索引。它返回给定索引处的值,若在索引处没有值,则返回nil

user=> (get [1 2 3] 1)
2
user=> (get [1 2 3] 4)
nil


5、assoc:
assoc接收三个参数:第一个是向量,第二个是整数索引,第三个是一个值。它返回一个新的向量,这个向量是原来那个向量在给定的索引处插入那个值的结果。如果索引超过了向量的长度,那么会引发一个错误。

user=> (assoc [1 2 3] 0 10)
[10 2 3]
user=> (assoc [1 2 3] 3 10)
[1 2 3 10]
user=> (assoc [1 2 3] 4 10)
IndexOutOfBoundsException clojure.lang.PersistentVector.assocN (PersistentVect
or.java:136)


6、subvec:
subvec接收两个或三个参数。第一个是向量,第二个和第三个(如果有的话)是索引。它返回一个新向量,这个向量由原来那个向量的介于两个索引之间或者第一个索引到向量末尾(如果没有第二个索引)的部分组成

user=> (subvec [12 3 4 5 6 7] 2)
[4 5 6 7]
user=> (subvec [12 3 4 5 6 7] 2 4)
[4 5]


7、rseq:
rseq接受一个向量参数,如果向量为空,则返回nil,如果不为空,则在常量时间内返回顺序逆转的新向量:

user=> (rseq [])
nil
user=> (rseq [3 5 9 1 3])
(3 1 9 5 3)
Clojure语言的数据类型 Clojure通过丰富的数据类型和集合机制,使得开发者能够以直观而高效的方式处理数据。无论是基本的数值、字符串,还是复杂的集合、映射,Clojure都为开发者提供了丰富的操作函数,结合不可变性设计,可以使程序更加健壮与易于维护。在实际开发中,合理利用这些数据类型和集合结构,能够使得Clojure程序更加简洁、清晰且具有良好的性能。希望本文对您理解Clojure的基本数据类型有所帮助,激发您在Clojure编程中探索更深层次的乐趣。 阅读详情

相关推荐

云架构师进阶【SAP迁移方案设计】手把手教您玩转SAP上云

一,项目背景介绍 今天又接到了北京某制造企业SAP迁移的场景,先简单说明一下,好好的SAP在运行着为什么要做迁移这类大动作呢?众所周知SAP的ERP是企业的绝对核心系统,尤其对于制造业更是核心的系统,这样一套核心系统还是生产环境在迁移的过程中必然要面临比较大的挑战,如果有任何问题的话,都会对企业的绩效产生很大的影响。 经过跟客户沟通才得知,客户的SAP原来的系统是托管在运营商机房里,近期感染了勒索病毒,导致业务宕机,SAP应用服务器无法启动,仅有的数据库服务器可以运行。基于上述情况公司领导当机立断决定迅

bdsh818的博客 4220

【clojure】入门篇-01

;定义一个symbol的a设置的值为hello,a值不可变;;定义局部的,直接返回了aa)ps:定义之后若要使用该函数名称,需要先执行一遍该定义的内容;;3.定义一个函数;;函数、后面跟的是一个参数列表,;;一个函数出现在列表的第一个元素位置的时候会被求值,这样就执行了这个元素;;给函数起一个名字;;通常使用 defn 函数名 参数列表 函数体。

前端代码小白的日常博客 1691

Python | 处理CMIP6 NC数据,以tas为例

各位同学,一般在文章最后一章我们可能会做不同气候情景下变量的未来时空变化特征,类似上图。从cmip6下载的nc数据常需要转换格式、裁剪到研究区和重采样等,本期代码可以解决这类问题。

qq_48539301的博客 1384

Clojure极简教程

Clojure是Lisp在JVM中运行的一种方言,所以可以预想其语言风格应该是括号之间的环环相扣。

微小冷的学习笔记 5410

SPI模式下的SD卡读写,为什么你的数据总出错?详解时序与状态机避坑指南

本文深入探讨SPI模式下SD卡读写数据出错的根本原因,提供时序优化与状态机设计的实战指南。针对时钟周期计数、状态机跳转和忙检测等核心问题,详解命令时序细节、状态机同步策略及高级避坑技巧,帮助开发者提升SD卡在SPI模式下的稳定性和性能。

weixin_30514745的博客 261

ENVI5.6 Seamless Mosaic多景影像镶嵌色差问题

多景影像无缝镶嵌色差问题拟解决方法

Matchaya的博客 7701

6 年专业Clojure经验分享 - Erez

Clojure 是一种很棒的编程语言,因为它具有函数性、缺乏对象/对原始值的关注以及通过其无缝 Java 互操作提供的庞大 JVM 生态系统 与其他编程语言相比,Clojure 工程师的招聘和构建工程团队具有挑战性,因为它不受欢迎,并且缺乏大量经验丰富的工程师 在主要与 Ruby 合作多年后,我来到了Nanit。那时我并不真正了解 Clojure,所以在我的第一阶段,我主要做 Ruby 工作以提供快速价值。从那以后 6 年多过去了,今天 Clojure 是我工具...

极道Jdon的技术博客 714

【开关电源】开关电源实战经验分享

开关电源原理设计、Layout设计经验分享

weixin_42098658的博客 4166

Clojure语言的语法糖

语法糖在Clojure中扮演着至关重要的角色,它为开发者提供了一种更为简洁高效的编程方式。在掌握了Clojure中的基本语法后,熟悉和利用语法糖能够显著提高开发者的编程效率与代码质量。通过从声明到执行的流畅表达,Clojure鼓励开发者以一种更自然的方式进行思考,专注于解决问题。随着Clojure社区的发展,越来越多的库和工具都在使用语法糖,帮助开发者快速构建和维护应用。通过不断地探索和实践,开发者不仅能提升自己的编程能力,还能够在代码中发现优雅的设计与丰富的表述方式。

2501_90770971的博客 740

使用 ANSYS AEDT(双向耦合)对高功率射频同轴滤波器进行热分析

使用 ANSYS HFSS,可以精确计算 EM 损耗,然后将其导入 ANSYS 热分析并使用 ANSYS Icepak CFD 求解器进行仿真,以帮助工程师解决最复杂的热挑战,并预测其设计在温度变化下的表现。然后,RF 损耗将与 ANSYS Icepak CFD 求解器耦合,以执行热分析,包括传热的传导、对流和辐射模式,并计算温度曲线。在此演示中,我们将仿真下面的 RF 同轴滤波器,并计算由于所用材料的有限电导率和介电损耗而导致的 RF 传导损耗。设置 HFSS 设计后,我们可以开始 HFSS 仿真。

jkh920184196的博客 1050

深度学习二分类实战:用Python+Keras搞定基因表达数据预测(附完整代码)

本文详细介绍了如何使用Python和Keras构建深度学习模型进行基因表达数据的二分类预测。通过数据预处理、特征选择、神经网络构建及优化策略,特别针对小样本场景提供了调参技巧和模型解释方法。文章还包含完整的代码示例,帮助读者快速掌握深度学习在生物信息学中的应用。

weixin_30642561的博客 245

clojure-基本语法-集合(二)

三、映射Map  Map存储一个键-值对的集合。键和值都可以是任何数据类型的对象,无论是基本数据类型还是其它映射。然而,使用关键字来作为映射的键非常合适,因此它们经常在应用映射的场合被使用。clojure的Map有三种实现方式:数组映射、哈希映射和有序映射。它们分别使用数组、哈希表和二叉树来作为底层实现。数组映射适用于较小的映射,而对哈希映射和有序映射的比较则要基于特定应用场合的情况。Map形式

codemosi的专栏,点击我可以跳到目录一栏 1371

基于深度学习YOLOv10的人脸表情识别系统(附完整资源+PySide6界面+训练代码)

本文介绍了如何基于YOLOv10实现一个人脸表情识别系统。我们从数据集准备、模型训练到PySide6界面实现进行了详细的讲解。通过该系统,用户可以实时检测和分类人脸表情,为情感分析、智能交互等应用场景提供支持。

YOLO 1053

通过Clojure中的集合与序列谈谈抽象的重要

通过JVM之上的语言Clojure讲解一下什么是抽象,以及抽象的好处。

码农无双的博客 1070

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: clojure-基本语法-符号及关键字
下一篇: clojure-基本语法-集合(二)
Dead_Knight
博客等级 码龄19年 6粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值