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

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -