如何在 Common Lisp 中创建多维数组?

How to create a multi-dimensional array in Common Lisp?

是否可以使用列表作为参数调用make-array函数?例如:

(make-array '((length '("a" "b")) (length '("r" "8" "5"))))

return:

#<TYPE-ERROR expected-type: NUMBER datum: (LENGTH '(...

即使我尝试使用以下命令转换 length 的结果:

(coerce (length '(1)) 'number)

它适用于一维数组但不适用于二维。

Is it possible to call make-array function with a list as parameter?

是的,事实上你总是要给它传递一个列表指定符,但它必须是整数[=的列表(或列表指定符) 53=]。列表 '((length '("a" "b")) (length '("r" "8" "5")))) 有两个列表作为其元素,而不是整数。例如,如果你这样做 (first '((length '("a" "b")) (length '("r" "8" "5"))))) ,你得到 (length '("a" "b")),而不是 2。你需要做 (make-array (list (length …) (length …)) …) 相反。

它在 HyperSpec 中 make-array 的文档中描述得很清楚:

Function MAKE-ARRAY

Syntax:

make-array dimensions &key element-type initial-element initial-contents adjustable fill-pointer displaced-to displaced-index-offset

=> new-array

Arguments and Values:

dimensions—a designator for a list of valid array dimensions.

例如,(make-array '(2 2)) returns 2 × 2 数组。或者,如果您需要动态计算维度,只需 list 将它们放在一起。例如,(make-array (list (length '(a b c)) (length '(d e)))) returns 一个 3 × 2 数组。

请注意,参数是列表的指定符。词汇表条目说:

list designator n. a designator for a list of objects; that is, an object that denotes a list and that is one of: a non-nil atom (denoting a singleton list whose element is that non-nil atom) or a proper list (denoting itself).

这意味着当您执行 (make-array 5) 时,5 实际上充当了 列表(5)。你真的可以认为 make-array 总是接受一个列表作为第一个参数,但是在单元素列表的情况下,你可以只传递单个元素,因为它是明确你想要什么。

相关

这些是相关的,但并不完全重复,因为它们是关于如何创建一个列表以传递给make-array,而这个问题是关于 是否 可以将列表传递给 make-array.

  • How to make an array with size received as arguments in a function in LISP?
  • How to modify this "make-matrix" function?

简单规则 1:如果您引用它,它不会被评估。

这是数据,不是代码:'((length '("a" "b")) (length '("r" "8" "5")))

为什么?因为它被引用了。

简单规则 2:如果你想计算一些东西,那就写 Lisp 代码,而不是文字数据。

(list 1 2) -> (1 2)

(list (length '(a b c)) (length '(1 2 3 4))) -> (3 4)

解决问题主题的一个未回答的方面:很像 Common Lisp 列表,多维数组也有文字表示,这在某些情况下很方便。

  • 列表
(list 'a 'b 'c)

;; is equivalent to

'(a b c)
  • 向量(一维数组)表示为 #[n](foo*) -- n,可选,是元素的数量,foo 是向量中的项目,例如
(vector 1 2 3 4)

;; is equivalent to

#4(1 2 3 4)

;; or

#(1 2 3 4)
  • 一个'proper'多维数组,即大于一维的数组,表示为:#nA<sequence> 其中n是维数,<sequence>有一个类似于嵌套列表的结构,例如
(make-array '(2 3) :initial-contents '((a b c) (d e f)))

;; is equivalent to the following. Note, the 'inner most' array arrays must have the same number of objects, i.e. lisp won't auto-fill them with nil or anything else.

#2A((A B C) (D E F))

但是你不需要记住那个。与许多其他形式一样,Lisp reader 接受它作为 make-array 输出的任何内容作为输入。 (考虑到一些我不会涉及的注意事项,或者更确切地说,将作为练习留给 reader!)