![](https://secure.gravatar.com/avatar/c7be29f230d0fc8df73e146bca8366fd.jpg?s=120&d=mm&r=g)
"James M. Lawrence" <llmjjmll@gmail.com> writes:
Using two loops seems awkward to me. How about one?
(defun delete-from-plist (plist &rest keys) (loop with head = plist with tail = nil for (key . rest) on plist by #'cddr do (assert rest () "Expected a proper plist, got ~S" plist) (if (member key keys :test #'eq) (let ((next (cdr rest))) (if tail (setf (cdr tail) next) (setf head next))) (setf tail rest)) finally (return head)))
I mention this for completeness and novelty, not for suitability: (defun sans (plist &rest keys) (let ((sans ())) (loop (let ((tail (nth-value 2 (get-properties plist keys)))) ;; this is how it ends (unless tail (return (nreconc sans plist))) ;; copy all the unmatched keys (loop until (eq plist tail) do (push (pop plist) sans) (push (pop plist) sans)) ;; skip the matched key (setq plist (cddr plist)))))) I don't think I've seen GET-PROPERTIES and NRECONC outside this function. I got it from here: http://xach.com/naggum/articles/3247672165664225%40naggum.no.html Zach