Sujet : Re: remove-if & remove-if-not for same sequence
De : Nobody447095 (at) *nospam* here-nor-there.org (B. Pym)
Groupes : comp.lang.lispDate : 27. Jun 2025, 22:47:17
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <103n3h2$cpsl$1@dont-email.me>
User-Agent : XanaNews/1.18.1.6
Tamas Papp wrote:
1. What would be the best name for this function? Is it already in a
(Quicklisp) library? (could not find it, don't want to reinvent the wheel).
--8<---------------cut here---------------start------------->8---
(defun separate-sequence (sequence predicate)
"Return two sequences of the same type, containing elements that
do and do not satisfy PREDICATE. Ordering of elements is preserved."
(values (remove-if (complement predicate) sequence)
(remove-if predicate sequence)))
;; Example
(separate-sequence '(0 1 2 3) #'oddp) ; => (1 3), (0 2)
--8<---------------cut here---------------end--------------->8---
2. Any suggestions for a better implementation (one that traverses the
sequence only once)? I came up with
--8<---------------cut here---------------start------------->8---
(defun separate-sequence (sequence predicate)
"Return two sequences of the same type, containing elements that do and do not satisfy PREDICATE. Ordering of elements is preserved."
(let (yes
no
(type (typecase sequence
(list 'list)
(vector `(simple-array ,(array-element-type sequence) '*))
(t (return-from separate-sequence
;; generic sequence, let built-ins handle it
(values (remove-if (complement predicate) sequence)
(remove-if predicate sequence)))))))
(map nil (lambda (element)
(if (funcall predicate element)
(push element yes)
(push element no)))
sequence)
(values (coerce (nreverse yes) type)
(coerce (nreverse no) type))))
Gauche Scheme
gosh> (partition even? (iota 20))
(0 2 4 6 8 10 12 14 16 18)
(1 3 5 7 9 11 13 15 17 19)