[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NMAP



When the topic of destructive mapping was first brought up, I thought
"What a great idea, but why not just write a function to do it?".
So I did.  My first attempt took about 5 minutes and looked like:
  (defun map-into (res-seq fn &rest arg-seqs)
    (let ((index 0))
      (apply #'map
	     nil
	     #'(lambda (&rest args)
	         (setf (elt res-seq index)
		       (apply fn args))
	         (incf index))
  	     arg-seqs)
      res-seq))
This worked and was quite elegant, but had the disadvantage that its
performance on lists could be much worse than its performance on vectors
because elt could be implemented to search from the beginning of the list
each time.  After thinking a bit, I made the following modifications:
  (defun map-into (res-seq fn &rest arg-seqs)
    (let ((rs res-seq)
	  (index 0))
      (apply #'map
	     nil
	     (if (listp res-seq)
	         #'(lambda (&rest args)
		     (setf (car rs) (apply fn args))
		     (pop rs))
	         #'(lambda (&rest args)
		     (setf (elt res-seq index)
			   (apply fn args))
		     (incf index)))
	     arg-seqs)
      res-seq))
This seems to handle the general case quite nicely and would seem to
generalize well into a macro for those of you who like them better.  This
assumes that the result sequence is big enough to handle the result of the
map (although it can be too big with no problem).  By the way, I also
(obviously) vote for MAP-INTO rather than NMAP.

	evan
-------