`
Dead_knight
  • 浏览: 1201073 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
752c8642-b795-3fe6-946e-a4e845bffdec
Spring Securi...
浏览量:240232
33caa84e-18a6-3036-a82b-6e2106a4de63
clojure专题
浏览量:48941
E17ca077-44df-3816-a3fe-471c43f6e1e5
WebLogic11g
浏览量:236878
社区版块
存档分类
最新评论

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

阅读更多
Clojure提供以下集合类型: list, vector, set, map。并且可以使用Java里面提供的集合类型。所有的clojure集合是不可修改的、异源的以及持久的。不可修改表示集合产生之后,不能从集合里面增加或删除元素。异源表示集合里面可以装任意类型的数据。持久的表示集合有更新时,更新之前的数据还在。CLojure以一种高效的,共享内存的方式来实现集合。
因为clojure里面的集合是不可修改的,所以也就没有对集合进行修改的函数。相反clojure里面提供了一些函数从一个已有的集合来高效地创建新的集合。同时也有一些函数操作一个已有的集合(比如vector)来产生另外一种类型的集合(比如LazySeq), 这些函数有不同的特性。
一、列表List
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次操作。

二、向量Vector
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)
1
0
分享到:
评论

相关推荐

    clojure-must-watch-源码.rar

    了解Clojure的基础语法,如S-expressions(符号表达式)、宏、动态类型以及如何定义和调用函数,是深入研究源码的前提。 2. **数据结构**:Clojure提供了多种内置数据结构,如列表、向量、映射、集合和范围。理解...

    programming-clojure-3rd

    这本书涵盖了从基础语法到高级特性的广泛内容,对于想要学习或提升Clojure技能的程序员来说,是一份宝贵的资源。 首先,Clojure的核心理念是简洁、并发和持久化数据结构。书中详细介绍了Clojure的语法特性,如S...

    clojure-basics-源码.rar

    5. **宏**(Macros):Clojure允许用户创建自己的语法,这是Lisp家族的一个重要特性。宏可以在编译时操作代码。 6. **REPL**:读-求值-打印-循环(Read-Eval-Print Loop)是Clojure开发的核心工具,用于快速测试...

    clojure-deps-edn:基于deps.edn的项目的有用配置和别名的集合

    它采用Clojure语法,使得配置文件本身可读性强,易于理解和维护。例如,你可以这样声明一个依赖: ```clojure {:deps {org.clojure/clojure {:mvn/version "1.10.3"}} :aliases {"dev" [:require [clojure.java....

    clojure-skattelisten-csv-parser

    Clojure,作为一种功能强大的 Lisp方言,凭借其简洁的语法和强大的数据处理能力,成为了处理CSV数据的理想工具。本文将以开源项目“clojure-skattelisten-csv-parser”为例,深入探讨如何使用Clojure高效地解析CSV...

    clojure-shopshop:一日研讨会的基本Clojure培训材料

    通过参与这个“clojure-shopshop”研讨会,学习者将全面了解Clojure的语法和设计理念,如使用REPL(Read-Eval-Print Loop)进行动态测试,理解Clojure的数据结构(如向量、列表、映射和集合),掌握函数式编程的核心...

    clojure-study-group:资料库和课程培训中心

    【clojure-study-group:资料库和课程培训中心】是一个专注于Clojure编程语言学习资源的集合,它提供了丰富的教程、示例代码、实践项目以及学习路径,旨在帮助开发者深入理解和掌握Clojure及其相关技术。Clojure是一...

    clojure-scripting:使用JVM Clojure编写脚本的第一步

    此外,理解Clojure的基本语法和数据结构,如列表、映射、向量和集合,以及函数式编程的核心概念,如高阶函数、闭包和递归,这些都是开始编写脚本的基础。 在标签中,“clojure”指的是我们关注的语言本身,...

    clojure-1.3.0

    Clojure是一种动态类型的语言,它的设计目标是提供一个简洁、强大且具有表达力的语法,适合处理复杂的数据结构。Clojure的运行环境是Java虚拟机(JVM),这使得它能够无缝地利用Java库和资源,同时保持高效的性能。...

    clojure-tetris:另一个 clojure 俄罗斯方块

    此外,对于那些已经熟悉其他编程语言的人来说,这个项目提供了一个探索Clojure独特之处的机会,比如其Lisp式的语法和对并行处理的支持。 总的来说,"clojure-tetris"是一个生动的示例,展示了Clojure如何被用于创建...

    clojure-by-example:针对Clojure的程序员的研讨会

    1. **基础语法**:介绍Clojure的基本语法,如S表达式、符号、数字、字符串、布尔值等,并演示如何在Clojure中读写这些基本类型。 2. **函数与高阶函数**:Clojure的函数是第一类公民,可以作为参数传递,也可以作为...

    clojure-misc:Clojure练习-不使用

    这个“clojure-misc”项目似乎是一系列Clojure语言的练习,旨在帮助学习者加深对Clojure语法、函数式编程特性和常用库的理解。 1. **函数式编程基础**: - Clojure鼓励使用函数来解决问题,避免使用副作用,这有助...

    clojure-algorithms:Clojure中的算法

    通过阅读和理解这些代码,你可以加深对Clojure语法的理解,掌握函数式编程的思维方式,并提升解决实际问题的能力。同时,该项目也是一个很好的起点,可以帮助你构建自己的Clojure算法库,进一步提升编程技能。 总结...

    learning-clojure-address-book:我在@JarrodCTaylor 精彩教程系列中取得的进展,关于如何使用 clojure 构建地址簿

    首先,我们需要了解Clojure的基本语法。Clojure以其特有的括号表达式(S-expressions)闻名,其中每个表达式都是一个可调用的对象。例如,`(defn name [params] body)` 是定义函数的语法,`name`是函数名,`params`...

    clojure-training:来自我在加尔各答 IBM 举办的 Clojure 培训研讨会的培训样本

    1. **课程大纲**:概述了培训的各个主题和学习目标,可能包括函数式编程基础、Clojure语法、数据结构、宏、多线程特性等。 2. **讲义和幻灯片**:详细讲解Clojure的各个方面,包括函数、序列、持久数据结构、REPL...

    clojure-examples:杂项 clojure 示例

    Clojure 是一种基于 Lisp 语法的函数式编程语言,它运行在 Java 虚拟机(JVM)上,充分利用了 JVM 的性能和生态系统。在这个名为 "clojure-examples" 的项目中,我们看到一系列的 Clojure 示例代码,旨在帮助开发者...

    clojure-dsl-resources:精选的Clojure资源列表,用于处理特定于域的语言

    "clojure-dsl-resources"是专门为那些希望在Clojure中构建DSL的开发者准备的一份精选资源集合,旨在帮助他们更高效地处理自然语言处理(NLP)、解析、数据转换等任务。 首先,DSL是一种设计语言,它针对某一特定...

    clojure-workshop-guide:使用Clojure进行功能编程的材料

    这个指南旨在帮助参与者逐步理解Clojure的基本概念、语法和特性,通过一系列的研讨会活动,深入掌握Clojure在实际开发中的应用。下面我们将详细探讨Clojure的核心知识点及其在实践中的应用。 首先,Clojure是基于...

    clojure cheatsheet-usletter-color.pdf

    通过以上解析可以看出,Clojure Cheat Sheet覆盖了Clojure语言的基本语法、内置函数、宏以及其他常用的功能,这对于初学者来说是一个非常有用的资源。它不仅帮助用户快速掌握Clojure的核心概念,还提供了实际编程中...

    gradle-rxjava-project-plugin-1.12.10.zip

    Clojure 是一种基于 Lisp 语法的函数式编程语言,它运行在 JVM 上,通常用于构建高性能、高并发的系统。Nebula 项目是一个由 Netflix 维护的 Gradle 插件集合,旨在解决大型企业级项目中常见的构建挑战。 【标签】...

Global site tag (gtag.js) - Google Analytics