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

[英]How do you copy an array in common lisp?


I'd like to make copies of my 2D array, which feels like the nice, functional, nondestructive way of handling arrays. What is the lispy way of doing this?

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

4 个解决方案

#1


14  

I use the following, which I believe is better than the alexandria version:

我使用以下,我相信它比亚历山大版更好:

(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))

The problem with the alexandria version is that the adjust-array hack causes the result (at least on SBCL) to never be a simple-array, which some other libraries (e.g. opticl) expect. The above version also was faster for me.

alexandria版本的问题在于adjust-array hack导致结果(至少在SBCL上)永远不会是一个简单的数组,其他一些库(例如opticl)期望。以上版本对我来说也更快。

Someone else has published a very similar version in a different library, but I forgot the names of both person and library.

其他人在不同的库中发布了一个非常相似的版本,但我忘记了人和库的名字。

#2


3  

The Common Lisp library Alexandria (installable through quicklisp) includes an implementation of copy-array for arbitrary ranks and dimensions:

Common Lisp库Alexandria(可通过quicklisp安装)包括任意排名和维度的复制数组实现:

(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)))

#3


1  

It depends how your 2D array is represented, and what flavor of Lisp are you using.

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

If you are using Common Lisp, then copy-seq could be useful.

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

#4


0  

If you want to do things the nice, functional, nondestructive way, then why do you even need to copy it?

如果你想以漂亮,实用,无损的方式做事,那你为什么还要复制呢?

  • if you're copying it in order to update it -- then you're not doing it the functional way.

    如果你要复制它以便更新它 - 那么你就不是以功能的方式来做它。

  • if you're doing it the functional way -- then you don't need a copy. You can just pass it anywhere and everywhere.

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

Maybe you want to transform it. In that case, you could use one of Lisp's many pure functions, such as mapcar or filter.

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


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2011/10/27/fbfa7dcaefecaddcdedf841ba8af98e3.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com