2013-11-22 2 views
1

Меня интересует численный анализ и недавно начал любовный роман с Common LISP. Я обнаружил, что мои мыслительные процессы сильно зависят от лет более императивного стиля программирования, поэтому я стремлюсь разработать более ленивый подход. Я полагаю, общая тема для тех, кто находится на пути LISP.Есть ли способ isf и setf несколько элементов массива?

В любом случае, считывая CLTL2, указывается, что к векторам можно обращаться в постоянное время, тогда как доступ к списку выполняется в линейном времени (раздел 2.5.1). Затем можно установить (setf (apply #'aref *some-vector* idx) new-value), чтобы установить одно место для вектора. Мой вопрос из двух частей:

a. Есть ли способ получить несколько значений массива, указав индексы списка, без необходимости перебирать список? Например, что-то похожее на правильную версию (map 'array #'aref *some-array* idx-list).

b. Есть ли способ установить значения некоторых элементов массива в том же духе, что и выше? Было бы идеально, чтобы иметь возможность применять функцию (через адекватно определенный map или до reduce и т. Д.) В список значений, извлеченных из массивов, например, для выборки и интерполяции.

Я также благодарен за любые комментарии относительно операций с массивами в целом и численные вычисления в частности (указатели на учебник или книгу, список рассылки, общие ошибки, когда использовать списки или другие структуры данных и т. Д.).

Cheers.

+0

Вопрос слишком широк. Stackoverflow посвящен проблемам программирования, а не общим советам. Ваш вопрос лучше описывает конкретную реальную проблему и поставляется с исходным кодом. –

+0

Вы должны заглянуть в блог Пола Хуонга - он проводит численные анализы с помощью CL: http://www.pvk.ca/ –

+0

@PaulNathan Будет, спасибо! – mangarju

ответ

2

а.

Вы можете получить карту, чтобы получить значения по индексу, как это:

(map 'vector #'(lambda (idx) (aref *some-array* idx)) idx-list) 

Обратите внимание, что это работает только для одномерных массивов. Более чем одномерная версия будет выглядеть так:

(map 'vector #'(lambda (idx) (apply #'aref *some-array* idx)) idx-list) 
0

Я не уверен, почему вы хотите избежать цикла, так как функция, такая как MAP, должна все равно работать.

Но вы можете использовать MAP в сочетании с функцией, которая создает циклический список, например.

(defun cycle (x) 
    (let ((result (list x))) 
     (setf (cdr result) result) 
    result)) 

(defun multiple-aref (array indices) 
    (map 'vector #'aref (cycle array) indices)) 

(multiple-aref '#(a b c d e f g) '(1 3 5)) 

=>#(B D F)

(cycle array) создает бесконечный список (array array array array ...). Но MAP все еще работает, потому что он рассматривает только множество элементов, как есть в . Самый короткий список дается (в данном случае '(1 2 3)).

+0

Очень интересно; ваш ответ освещается косой.Было бы неплохо, если бы возвращаемые значения были 'setf'-able, но сделали бы достаточно материала для другого сообщения. – mangarju

3

b. Вы можете назначить несколько последовательных значений сразу:

(setf (subseq vector start end) values) 
Смежные вопросы