如何在常见的lisp中复制数组?

时间:2011-10-27 06:04:06

标签: arrays functional-programming common-lisp

我想复制我的2D数组,感觉就像处理数组的漂亮,功能,非破坏性的方式。这样做的方式是什么?

4 个答案:

答案 0 :(得分:15)

更新:现在,alexandriacopy-array非常类似于下面给出的实现。使用它。

已废除的答案:我使用了以下内容,我认为它比当时的亚历山大版更好:

(defun copy-array (array &key
                   (element-type (array-element-type array))
                   (fill-pointer (and (array-has-fill-pointer-p array)
                                      (fill-pointer array)))
                   (adjustable (adjustable-array-p array)))
  "Returns an undisplaced copy of ARRAY, with same fill-pointer and
adjustability (if any) as the original, unless overridden by the keyword
arguments."
  (let* ((dimensions (array-dimensions array))
         (new-array (make-array dimensions
                                :element-type element-type
                                :adjustable adjustable
                                :fill-pointer fill-pointer)))
    (dotimes (i (array-total-size array))
      (setf (row-major-aref new-array i)
            (row-major-aref array i)))
    new-array))

亚历山大版的问题在于adjust-array hack导致结果(至少在SBCL上)永远不会成为a simple-array,其他一些图书馆(例如视频)期望的。该 以上版本对我来说也更快。

其他人在另外发布了一个非常相似的版本 图书馆,但我忘记了人和图书馆的名字。

答案 1 :(得分:3)

Common Lisp库Alexandria(可通过quicklisp安装)包含copy-array对任意排名和维度的实现:

(defun copy-array (array &key
                   (element-type (array-element-type array))
                   (fill-pointer (and (array-has-fill-pointer-p array)
                                      (fill-pointer array)))
                   (adjustable (adjustable-array-p array)))
  "Returns an undisplaced copy of ARRAY, with same fill-pointer and
adjustability (if any) as the original, unless overridden by the keyword
arguments. Performance depends on efficiency of general ADJUST-ARRAY in the
host lisp -- for most cases a special purpose copying function is likely to
perform better."
  (let ((dims (array-dimensions array)))
    ;; Dictionary entry for ADJUST-ARRAY requires adjusting a
    ;; displaced array to a non-displaced one to make a copy.
    (adjust-array
     (make-array dims
                 :element-type element-type :fill-pointer fill-pointer
                 :adjustable adjustable :displaced-to array)
     dims)))

答案 2 :(得分:1)

这取决于您的2D数组的表示方式,以及您使用的Lisp风格。

如果您使用的是Common Lisp,那么copy-seq可能会有用。

答案 3 :(得分:0)

如果你想做the nice, functional, nondestructive way的事情,那为什么你甚至需要复制它?

  • 如果您要复制它以便更新它 - 那么您就不会以功能方式进行复制。

  • 如果您正在以功能方式进行 - 那么您不需要副本。你可以随时随地传递它。

也许你想改变它。在这种情况下,您可以使用Lisp的许多纯函数之一,例如mapcarfilter