Clojure 学习入门(19)—— 数组

2024-02-15 03:08
文章标签 数组 学习 入门 19 clojure

本文主要是介绍Clojure 学习入门(19)—— 数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、创建数组

1.1 从集合创建数组 into-array

into-array

(into-array aseq) 
(into-array type aseq)

示例:

user=> (into-array [1 2 3])
#<Integer[] [Ljava.lang.Integer;@4b0ea9ba>
user=> (seq (into-array [1 2 3]))
(1 2 3)

返回包含aset中所有元素的数组。数组的组件类型为type(如果指定了type),或aset中第一个元素的类型(如果aset不为空),或Object。aset中所有元素的类型必须兼容数组的组件类型。type可以使用基本类型的类对象,例如Integer/TYPE等。

Added in Clojure version 1.0 
Source


(into-array aseq)

1(into-array [])    ; #<Object[]> - []
2(into-array [1 2 3])    ; #<Long[]> - [123],注:into-array返回的不是原生数组,而是引用数组

示例:

user=> (into-array [])
#<Object[] [Ljava.lang.Object;@26ae533a>
user=> (into-array Integer/TYPE [1 2 3])
#<int[] [I@2cba5bdb>
user=> (into-array Long/TYPE [1 2 3])
#<long[] [J@373c0b53>
user=> (seq (into-array Long/TYPE [1 2 3]))
(1 2 3)

(into-array type aseq)

1(into-array Integer/TYPE [1 2 3])     ; #<int[]> - [123]
2; 等效于(int-array [1 2 3])


1.2 创建空数组 make-array

make-array

(make-array type len) 
(make-array type dim & more-dims)

创建并返回一个指定类型、指定尺寸的数组。需要注意是类对象是必需的。类对象可以通过导入或完全限定名称获得。type可以使用基本类型的类对象,例如Integer/TYPE等。

Added in Clojure version 1.0 
Source


(make-array type len)

1(make-array Integer/TYPE 10)     ; #<int[]> - [0000000000]
2; 等效于(int-array 10)

(make-array type dim & more-dims)

1(make-array Integer/TYPE 2 10)     ;二维数组 #<int[][]> - [[I@4b8bc0fb, [I@442ac57c]
2(make-array Integer/TYPE 2 2 10)     ;三维数组 #<int[][][]> - [[[I@17f7b44f, [[I@75ebad4]


1.3 创建基本类型数组 int-array

int-array

(int-array size-or-seq) 
(int-array size init-val-or-seq)

创建一个int数组

Added in Clojure version 1.0 
Source

示例:

user=> (int-array 10)
#<int[] [I@6490832e>
user=> (seq (int-array 10))
(0 0 0 0 0 0 0 0 0 0)
user=> (double-array 10 1.24)
#<double[] [D@2f87c55c>
user=> (seq (double-array 10 1.24))
(1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24 1.24)

同系列的全部方法

  1. byte-array
  2. short-array
  3. int-array
  4. long-array
  5. float-array
  6. double-array
  7. char-array
  8. boolean-array
  9. object-array*

object-array只有(object-array size-or-seq)用法

(int-array size)

1(int-array 3)     ; #<int[]> - [000]
2; 相当于(make-array Integer/TYPE 3)

(int-array seq)

1(int-array [1 2 3])     ; #<int[]> - [123]
2; 相当于(into-array Integer/TYPE [1 2 3])

(int-array size init-val)

1(int-array 3 5)     ; #<int[]> - [555]

(int-array size seq)

1(int-array 5 [1 2 3])     ; #<int[]> - [12300]
2(int-array 5 [1 2 3 4 5 6 7])     ; #<int[]> - [12345]


2、 访问和修改数组

2.1 访问数组的值 aget

aget

(aget array idx) 
(aget array idx & idxs)

返回指定索引的值。可用于所有类型的Java数组。(等效于array[idx])

Added in Clojure version 1.0 
Source

1(let [arrs (into-array
2             [(int-array [1 2 3])
3              (int-array [11 12 13 14 15])])]
4  ; #<int[][]> [[123], [1112131415]]
5  (println (aget arrs 0 2))
6  3
7  (println (aget arrs 1 4)))
8  15

2.2 修改数组的值 aset

aset

(aset array idx val) 
(aset array idx idx2 & idxv)

用指定的元素替代数组中索引位置上的元素。可用于引用类型的Java数组。返回val。

Added in Clojure version 1.0 
Source

(aset array idx val)

1(let [arr (object-array ["A" "B" "C" "D" "E"])
2      ; [A, B, C, D, E]
3      val (aset arr 2 "F")]
4  (println val))
5; arr: [A, B, F, D, E]
6; val: F

示例:

(let [arr (object-array ["A" "B" "C" "D" "E"])val (aget arr 2)val2 (aset arr 2 "F")](println val)  ; C(println val2) ; F)
(aset array idx idx2 & idxv)

01// Java
02public static Object[][][] arr3d = {
03            {
04                    {
05                            "A""B""C""D""E"
06                    },
07                    {
08                            "1""2""3""4""5"
09                    }
10            },
11            {
12                    {
13                            'a''b''c''d''e'
14                    },
15                    {
16                            1112131415
17                    }
18            }
19    };// 用Clojure初始化多维数组实在是太蛋疼了
20 
21; clojure
22(let [val1 (aset arr3d 0 0 0 "val1")
23      val2 (aset arr3d 0 1 0 "val2")
24      val3 (aset arr3d 1 0 0 "val3")
25      val4 (aset arr3d 1 1 0 "val4")]
26  (println (java.util.Arrays/toString (aget arr3d 0 0)))
27  (println (java.util.Arrays/toString (aget arr3d 0 1)))
28  (println (java.util.Arrays/toString (aget arr3d 1 0)))
29  (println (java.util.Arrays/toString (aget arr3d 1 1))))
30; [val1, B, C, D, E]
31; [val2, 2345]
32; [val3, b, c, d, e]
33; [val4, 12131415]

aset-int

(aset-int array idx val) 
(aset-int array idx idx2 & idxv)

用指定的元素替代数组中索引位置上的元素。可用于int类型的Java数组。返回val。

Added in Clojure version 1.0 
Source

同系列全部方法

  1. aset-byte
  2. aset-short
  3. aset-int
  4. aset-long
  5. aset-float
  6. aset-double
  7. aset-char
  8. aset-boolean
  9. aset

2.3 计算数组长度 alength

alength

(alength array)

返回Java数组的长度。可用于所有类型的数组。

Added in Clojure version 1.0 
Source

1(alength (char-array 11 \a))     ; 11
2; 等效于(count (char-array 11 \a))

2.4 使用Clojure序列库

2.4.1 通用版序列库
1; clojure.lang.LazySeq
2; clojure.lang.LazySeq
2.4.2 数组专用序列库 amap, areduce

amap 宏

(amap a idx ret expr)

用表达式expr映射数组a。使用一个索引idx,和一个返回值ret,并将ret初始化为数组a的克隆,然后将ret的每一个元素应用于expr表达式,(用表达式的返回值替换ret当前值)最后返回新的ret数组。

Added in Clojure version 1.0 
Source

1; 为数组的每个值加2
2(let [arr (int-array [1 2 3])
3      ret (amap arr idx ret (do
4                              (println "=" (vec ret))
5                              (+ 2 (aget ret idx))))]
6  (println (vec ret)))

示例:

(let [arr (int-array [1 2 3])ret (amap arr idx ret (do (println "=" (vec ret))(+ 2 (aget ret idx))))](println (vec ret)));= [1 2 3]
;= [3 2 3]
;= [3 4 3]
;[3 4 5]

areduce 宏

(areduce a idx ret init expr)

用表达式expr归纳数组a。使用一个索引idx,和一个返回值ret,将ret初始化为init,将ret设置为expr表达式每一步的计算结果,最后返回ret。

Added in Clojure version 1.0 
Source

1; 计算数组[12, .., 100]每个元素的和
2(let [arr (int-array (range 1 101))
3      ret (areduce arr idx ret 0 (+ ret (aget arr idx)))]
4  (println ret))
55050


3、 其他

3.1 类型转换 ints

  • bytes `Casts to bytes[]` Added in Clojure version 1.1
  • shorts `Casts to shorts[]` Added in Clojure version 1.1
  • ints `Casts to int[]` Added in Clojure version 1.0
  • longs `Casts to long[]` Added in Clojure version 1.0
  • floats `Casts to float[]` Added in Clojure version 1.0
  • doubles `Casts to double[]` Added in Clojure version 1.0
  • chars `Casts to chars[]` Added in Clojure version 1.1
  • booleans `Casts to boolean[]` Added in Clojure version 1.1

引用类型可以用to-array

3.2 数组克隆 aclone

aclone

(aclone array)

返回Java数组的拷贝。可用于已知类型的数组。

Added in Clojure version 1.0 
Source


4、总结

生活中一怕没有选择,二怕选择过多。创建数组的方法太多也会使思维混乱。一般而言对于引用类型的对象,使用集合容器远优于使用数组。所以使用数组的场景就只有处理基本类型数据(并且对性能有一定要求)的情况了,因此个人推荐优先使用int-array等方法创建数组。 
花了一天时间,翻了好几本书,几乎找遍了与数组相关的所有方法,希望没有遗漏的。Clojure数组专题到此为止,之后会继续以专题的形式总结其他的API。

========2013/11/4 
Clojure操作多维数组的aset, aget性能简直让人无法直视,用来写算法还是算了吧。

========2013/12/8 
直接使用into-array函数返回的不是原生数组,而是一个引用数组。如果要用into-array创建原生数组,必须指定类型(第一个参数)。之前没注意这个,在《The Joy Of Clojure》中看到。


附录:

user=> (find-doc "-array")

user=> (find-doc "-array")
-------------------------
clojure.core/boolean-array
([size-or-seq] [size init-val-or-seq])Creates an array of booleans
-------------------------
clojure.core/byte-array
([size-or-seq] [size init-val-or-seq])Creates an array of bytes
-------------------------
clojure.core/char-array
([size-or-seq] [size init-val-or-seq])Creates an array of chars
-------------------------
clojure.core/double-array
([size-or-seq] [size init-val-or-seq])Creates an array of doubles
-------------------------
clojure.core/float-array
([size-or-seq] [size init-val-or-seq])Creates an array of floats
-------------------------
clojure.core/int-array
([size-or-seq] [size init-val-or-seq])Creates an array of ints
-------------------------
clojure.core/into-array
([aseq] [type aseq])Returns an array with components set to the values in aseq. The array'scomponent type is type if provided, or the type of the first value inaseq if present, or Object. All values in aseq must be compatible withthe component type. Class objects for the primitive types can be obtainedusing, e.g., Integer/TYPE.
-------------------------
clojure.core/long-array
([size-or-seq] [size init-val-or-seq])Creates an array of longs
-------------------------
clojure.core/make-array
([type len] [type dim & more-dims])Creates and returns an array of instances of the specified class ofthe specified dimension(s).  Note that a class object is required.Class objects can be obtained by using their imported orfully-qualified name.  Class objects for the primitive types can beobtained using, e.g., Integer/TYPE.
-------------------------
clojure.core/short-array
([size-or-seq] [size init-val-or-seq])Creates an array of shorts
-------------------------
clojure.core/to-array
([coll])Returns an array of Objects containing the contents of coll, whichcan be any Collection.  Maps to java.util.Collection.toArray().
-------------------------
clojure.core/to-array-2d
([coll])Returns a (potentially-ragged) 2-dimensional array of Objectscontaining the contents of coll, which can be any Collection of anyCollection.
nil


参考推荐:

Clojure API之数组操作


这篇关于Clojure 学习入门(19)—— 数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/710300

相关文章

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和