Shammer's Philosophy

My private adversaria

Lispで配列の要素数を調べる

make-array関数で配列を作ることができる、というのは[Lisp] - Shammerismですでに試してみた。一歩進んで、作成された配列の要素数を調べてみる。length関数を使用すればできるかと思ったが、多次元配列だとうまくいかなかった。

> (setq array1 (make-array '(2 3) :initial-element 0))
#2A((0 0 0) (0 0 0))
>(length array1)
#1=#2A((0 0 0) (0 0 0)) is not a SEQUENCE

lengthは、一次元配列(Vector)のみに使用できる。多次元配列の場合は、別の方法があるようだ。17.3. Array Informationを参照したところ、使用するのはarray-rankとarray-dimensionとarray-total-sizeを使用すればできそう。上記に続いて、これら2つの関数を以下のように試してみた。

>(array-rank array1)
2
>(array-dimension array1 0)
2
>(array-dimension array1 1)
3
>(array-total-size array1)
6

それぞれの関数の定義のみ抜粋。

  • This(array-rank) returns the number of dimensions (axes) of array. This will be a non-negative integer. See array-rank-limit.
  • array-dimensions returns a list whose elements are the dimensions of array.
  • array-total-size returns the total number of elements in the array, calculated as the product of all the dimensions.Note that the total size of a zero-dimensional array is 1. The total size of a one-dimensional array is calculated without regard for any fill pointer.

array-rankと、array-dimensionの使い分けがよくわからない。今回の場合は、一つ一つの多次元配列内の配列一つ一つがすべて同じとわかっているが、これが文字列の配列だと各要素の文字数がすべて同じとは限らない。こうした場合は、多次元配列の一つ目だけを抜き出して、要素数をカウントする、という作業が必要になるかもしれない。こういう場合にarray-dimensionを使うべきなのか?文字列の配列を作って試してみよう。


これらの作業が本当にLispで何かプログラムしよう、という時に必要になるかどうかはわからないが(配列よりリストを使うことが多そう)、とりあえず勉強のためだ。