[alexandria-devel] Implementation of DELETE-FROM-PLIST
Stas Boukarev
stassats at gmail.com
Sun Feb 24 16:03:35 UTC 2013
Zach Beane <xach at xach.com> writes:
> "James M. Lawrence" <llmjjmll at 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
If striving for shortness:
(defun delete-from-plist (plist &rest keys)
(dolist (key keys plist)
(remf plist key)))
--
With best regards, Stas.
More information about the alexandria-devel
mailing list