【问题标题】:How to create a multi-dimensional array in Common Lisp?如何在 Common Lisp 中创建多维数组?
【发布时间】:2015-02-18 14:09:11
【问题描述】:

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

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

返回:

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

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

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

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

【问题讨论】:

    标签: common-lisp


    【解决方案1】:

    是否可以以列表为参数调用make-array函数?

    是的,事实上你总是必须给它传递一个列表designator,但它必须是一个整数的列表(或列表指示符)。列表 '((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 中的 ma​​ke-array 的文档中有非常清楚的描述:

    函数MAKE-ARRAY

    语法:

    ma​​ke-array 尺寸和关键元素类型初始元素初始内容可调整填充指针移位到 位移索引偏移量

    => 新数组

    参数和值:

    维度——有效数组维度列表的指示符。

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

    注意,参数是列表的designator。词汇表条目说:

    list designatorn。对象列表的指示符;也就是说,一个 表示一个列表的对象,它是以下之一:非零原子 (表示一个单例列表,其元素是那个非零原子)或 正确的列表(表示它自己)。

    这意味着当你执行 (make-array 5) 时,5 实际上是作为 list 的指示符 >(5)。你真的可以认为 ma​​ke-array 总是接受一个列表作为第一个参数,但是在单元素列表的情况下,你可以只传递单个元素,因为它是明确的会想要的。

    相关

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

    【讨论】:

      【解决方案2】:

      简单的规则 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)
      

      【讨论】:

        【解决方案3】:

        解决问题的一个未回答的方面:与 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)
        
        • “正确”多维数组,即大于一维的数组,表示为:#nA&lt;sequence&gt; 其中n 是维数,&lt;sequence&gt; 具有类似于嵌套列表的结构,例如李>
        (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 阅读器接受它作为 make-array 输出的任何内容作为输入。 (考虑到一些我不会深入的警告,或者更确切地说,作为练习留给读者!)

        【讨论】:

          猜你喜欢
          • 2020-11-01
          • 2012-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多