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

相关文章

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

详解Spring Boot接收参数的19种方式

《详解SpringBoot接收参数的19种方式》SpringBoot提供了多种注解来接收不同类型的参数,本文给大家介绍SpringBoot接收参数的19种方式,感兴趣的朋友跟随小编一起看看吧... 目录SpringBoot接受参数相关@PathVariable注解@RequestHeader注解@Reque

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用