I think it should work - arrays are indeed sequences.
(let* ((an-array (make-array 6 :initial-contents '(#\f #\o #\o #\b #\a #\r)))
(f-pos (position #\f an-array))
(r-pos (position #\r an-array)))
(rotatef (elt an-array f-pos)
(elt an-array r-pos))
an-array)
;=> #(#\r #\o #\o #\b #\a #\f)
Of course, you don't need to bind the positions to names. This will work too:
(let ((an-array (make-array 6 :initial-contents '(#\f #\o #\o #\b #\a #\r))))
(rotatef (elt an-array (position #\f an-array))
(elt an-array (position #\r an-array)))
an-array)
;=> #(#\r #\o #\o #\b #\a #\f)
If the problem is with position
not finding the element you need, its :test
argument may be helpful. There are also position-if
and position-if-not
functions which let you supply your own predicate for identifying the element. All three are described here in the HyperSpec.
Here's an example that probably won't work without the :test
argument, since the default (which is eql
for all sequence functions with :test
arguments - see table 11-2 here for a nice summary of the standard sequence function keyword arguments) doesn't work on lists.
(let ((an-array (make-array 3 :initial-contents '((1 2 3)
(4 5 6)
(7 8 9)))))
(rotatef (elt an-array (position '(1 2 3) an-array :test #'equal))
(elt an-array (position '(7 8 9) an-array :test #'equal)))
an-array)
;=> ((7 8 9) (4 5 6) (1 2 3))
(Tested on SBCL 1.0.55.0.debian).
Added:
Here's a brute force way to do it with a two-dimensional array. find-position
assumes the array is of size (3 3)
but it would be easy to make it somewhat more general.
I don't advocate this as the best solution, but I didn't want to leave you empty handed after misunderstanding your question :)
(defvar an-array #2A((1 2 3) (4 5 6) (7 8 9)))
(defun find-position (array item &key (test #'eql))
(loop for i below 3 do
(loop for j below 3 do
(when (funcall test (aref array i j) item)
(return-from find-position (list i j))))))
(defun swap-4-and-7 (array)
;; Example use
(destructuring-bind (i1 j1) (find-position array 4)
(destructuring-bind (i2 j2) (find-position array 7)
(rotatef (aref array i1 j1)
(aref array i2 j2))))
array)
(swap-4-and-7 an-array)
;=> #2A((1 2 3) (7 5 6) (4 8 9))