I would not write this function because, as Rainer Hoswig says , the standard already provides SET-DIFFERENCE . However, if I had to implement a function implementation, I would use this:
(defun filter (ab) (let ((table (make-hash-table))) (map 'nil (lambda (e) (setf (gethash e table) t)) a) (remove-if (lambda (e) (gethash e table)) b)))
The implementation of this method provides several advantages, the most important thing is that it only bypasses b once; using a hash table to keep track of which elements are in a is likely to be much better if a longer.
In addition, the use of common sequence functions, such as MAP and REMOVE-IF , means that this function can be used with strings and vectors, as well as with lists, which is an advantage even over the standard SET-DIFFERENCE . The main drawback of this approach is that you want to extend the function with an argument :TEST , which allows the user to provide an equality predicate other than the default EQL , since CL hash tables only work with a small number of pre-defined equality predicates ( EQ , EQL , EQUAL and EQUALP ).
source share