Re: Straight From the Trenches Nooby Stumper Dunk the Kenny Gotta Be A Shorter Cleaner Way #26



Ariel Badichi wrote:
On Jan 16, 7:12 pm, Pascal Costanza <p...@xxxxxxxxx> wrote:
(defun excise-ranges-helper (vector ranges)
(declare (vector vector))
(loop with nada = vector ;; ;)
for (lower upper) in ranges
do (fill vector nada :start lower :end (1+ upper))
finally (return (loop for entry across vector
unless (eq entry nada)
collect entry))))

(defgeneric excise-ranges (sequence ranges)
(:method ((sequence vector) ranges)
(coerce (excise-ranges-helper (copy-seq sequence) ranges) 'vector))
(:method ((sequence list) ranges)
(excise-ranges-helper (coerce sequence 'vector) ranges)))


That's a good approach, but there are some unnecessary complications
here. I would write the following:

(defun excise-ranges (sequence ranges)
(loop with nada = (load-time-value (cons nil nil))
for (lower upper) in ranges
do (fill sequence nada :start lower :end (1+ upper))
finally (return (remove nada sequence :test #'eq))))

Note that I use a "private" cons, which is guaranteed not to be an
element
of the sequence at function entry or exit.

That's also true for the value I use in my code, because the vector that I use as a marker is a freshly created vector. But, indeed, I meant that as a joke. ;)

Note that the sequence is
passed
just to FILL and REMOVE, which are generic sequence operators - no
need
to coerce anything.

Nice, also wrt to using DELETE, as you state in your own follow-up.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
.



Relevant Pages