Как мы можем элегантно преобразовывать между произвольно вложенными списками и массивами?
например.
((1 2 3) (4 5 6))
становится
#2A((1 2 3) (4 5 6))
и наоборот
Как мы можем элегантно преобразовывать между произвольно вложенными списками и массивами?
например.
((1 2 3) (4 5 6))
становится
#2A((1 2 3) (4 5 6))
и наоборот
Список массивов 2d:
(defun list-to-2d-array (list)
(make-array (list (length list)
(length (first list)))
:initial-contents list))
2d для списка:
(defun 2d-array-to-list (array)
(loop for i below (array-dimension array 0)
collect (loop for j below (array-dimension array 1)
collect (aref array i j))))
Многомерная форма для списка на 2d проста.
(defun list-dimensions (list depth)
(loop repeat depth
collect (length list)
do (setf list (car list))))
(defun list-to-array (list depth)
(make-array (list-dimensions list depth)
:initial-contents list))
Массив для списка сложнее.
Возможно, что-то вроде этого:
(defun array-to-list (array)
(let* ((dimensions (array-dimensions array))
(depth (1- (length dimensions)))
(indices (make-list (1+ depth) :initial-element 0)))
(labels ((recurse (n)
(loop for j below (nth n dimensions)
do (setf (nth n indices) j)
collect (if (= n depth)
(apply #'aref array indices)
(recurse (1+ n))))))
(recurse 0))))
Еще один массив 2d для списка решений:
(defun 2d-array-to-list (array)
(map 'list #'identity array))
И список для 2d массива (но, возможно, не так эффективен, как решение последнего ответа):
(defun list-to-2d-array (list)
(map 'array #'identity list))