lisp - Filter a list into two parts by a predicate -
i want do
(filter-list-into-two-parts #'evenp '(1 2 3 4 5)) ; => ((2 4) (1 3 5))
where list split 2 sub-lists depending on whether predicate evaluates true. easy define such function:
(defun filter-list-into-two-parts (predicate list) (list (remove-if-not predicate list) (remove-if predicate list)))
but know if there built-in function in lisp can this, or perhaps better way of writing function?
i don't think there built-in , version suboptimal because traverses list twice , calls predicate on each list element twice.
(defun filter-list-into-two-parts (predicate list) (loop x in list if (funcall predicate x) collect x yes else collect x no (return (values yes no))))
i return 2 values instead of list thereof; more idiomatic (you using multiple-value-bind
extract yes
, no
multiple values returned, instead of using destructuring-bind
parse list, conses less , faster).
a more general version be
(defun split-list (key list &key (test 'eql)) (let ((ht (make-hash-table :test test))) (dolist (x list ht) (push x (gethash (funcall key x) ht '()))))) (split-list (lambda (x) (mod x 3)) (loop 0 9 collect i)) ==> #s(hash-table :test fasthash-eql (2 . (8 5 2)) (1 . (7 4 1)) (0 . (9 6 3 0)))
Comments
Post a Comment