Я хотел бы сделать копии своего 2D-массива, который выглядит как хороший, функциональный, неразрушающий способ обработки массивов. Что это за липкий способ сделать это?
Как скопировать массив в общий lisp?
Ответ 1
Я использую следующее, которое, я считаю, лучше, чем версия александрии:
(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) никогда не будет
simple-array
, который ожидают некоторые другие библиотеки (например, opticl).
выше версия также была быстрее для меня.
Кто-то опубликовал очень похожую версию в другом библиотеке, но я забыл имена как человека, так и библиотеки.
Ответ 2
Общая 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)))
Ответ 3
Это зависит от того, как представлен ваш 2D-массив, и какой вкус Lisp вы используете.
Если вы используете Common Lisp, то copy-seq может быть полезным.
Ответ 4
Если вы хотите делать что-то the nice, functional, nondestructive way
, то почему вам даже нужно его скопировать?
-
если вы копируете его, чтобы обновить его, - тогда вы не выполняете его функциональным способом.
-
если вы делаете это функционально - тогда вам не нужна копия. Вы можете просто передать его везде и всюду.
Возможно, вы хотите его преобразовать. В этом случае вы можете использовать одну из Lisp многих чистых функций, таких как mapcar
или filter
.