Clojure API之数组操作

##1、创建数组## ###1.1 从集合创建数组 into-array### into-array

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

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

Added in Clojure version 1.0
Source

(into-array aseq)

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

(into-array type aseq)

(into-array Integer/TYPE [1 2 3])     ; #<int[]> - [1, 2, 3]
; 等效于(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)

(make-array Integer/TYPE 10)     ; #<int[]> - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
; 等效于(int-array 10)

(make-array type dim & more-dims)

(make-array Integer/TYPE 2 10)     ;二维数组 #<int[][]> - [[I@4b8bc0fb, [I@442ac57c]
(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

同系列的全部方法

  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)

(int-array 3)     ; #<int[]> - [0, 0, 0]
; 相当于(make-array Integer/TYPE 3)

(int-array seq)

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

(int-array size init-val)

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

(int-array size seq)

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

##2、 访问和修改数组##

###2.1 访问数组的值 aget### aget

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

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

Added in Clojure version 1.0
Source

(let [arrs (into-array
             [(int-array [1 2 3])
              (int-array [11 12 13 14 15])])]
  ; #<int[][]> [[1, 2, 3], [11, 12, 13, 14, 15]]
  (println (aget arrs 0 2))
  ; 3
  (println (aget arrs 1 4)))
  ; 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)

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

(aset array idx idx2 & idxv)

// Java
public static Object[][][] arr3d = {
			{
					{
							"A", "B", "C", "D", "E"
					},
					{
							"1", "2", "3", "4", "5"
					}
			},
			{
					{
							'a', 'b', 'c', 'd', 'e'
					},
					{
							11, 12, 13, 14, 15
					}
			}
	};// 用Clojure初始化多维数组实在是太蛋疼了

; clojure
(let [val1 (aset arr3d 0 0 0 "val1")
      val2 (aset arr3d 0 1 0 "val2")
      val3 (aset arr3d 1 0 0 "val3")
      val4 (aset arr3d 1 1 0 "val4")]
  (println (java.util.Arrays/toString (aget arr3d 0 0)))
  (println (java.util.Arrays/toString (aget arr3d 0 1)))
  (println (java.util.Arrays/toString (aget arr3d 1 0)))
  (println (java.util.Arrays/toString (aget arr3d 1 1))))
; [val1, B, C, D, E]
; [val2, 2, 3, 4, 5]
; [val3, b, c, d, e]
; [val4, 12, 13, 14, 15]

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

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

###2.4 使用Clojure序列库###

####2.4.1 通用版序列库####

(map #(Character/toUpperCase %) (.toCharArray "Clojure"))
; 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

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

areduce

(areduce a idx ret init expr)

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

Added in Clojure version 1.0
Source

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

##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》中看到。

转载于:https://my.oschina.net/u/580483/blog/159989

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值