position - Lisp array element swap -
i'm new lisp , i'm trying trade 2 elements in array. know if there function specified position can use rotatef swap them.
i've tried function position doesn't work on arrays since isn't sequence.
what best computational solution in case there isn't built in function array?
i've searched around , can't seem find simple solution. row-major-aref solution?
basically, want find position of element in 2 dimensional array , return position used in rotatef
i think should work - arrays 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, don't need bind positions names. 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 problem position
not finding element need, :test
argument may helpful. there position-if
, position-if-not
functions let supply own predicate identifying element. 3 described here in hyperspec.
here's example won't work without :test
argument, since default (which eql
sequence functions :test
arguments - see table 11-2 here nice summary of 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 brute force way two-dimensional array. find-position
assumes array of size (3 3)
easy make more general.
i don't advocate best solution, didn't want leave empty handed after misunderstanding question :)
(defvar an-array #2a((1 2 3) (4 5 6) (7 8 9))) (defun find-position (array item &key (test #'eql)) (loop below 3 (loop j below 3 (when (funcall test (aref array j) item) (return-from find-position (list 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))
Comments
Post a Comment