... |
... |
@@ -755,13 +755,23 @@ |
755
|
755
|
;; value of RES, which holds the result of the set function.
|
756
|
756
|
;; TEST-FORM is a form that tests whether to add the item from LIST1
|
757
|
757
|
;; to RES.
|
758
|
|
-(defmacro process-set (init-res test-form)
|
|
758
|
+(defmacro process-set-body (init-res invert-p test-form)
|
759
|
759
|
`(let ((res ,init-res))
|
760
|
760
|
(dolist (item list1)
|
761
|
|
- (when ,test-form
|
|
761
|
+ (when ,(if invert-p
|
|
762
|
+ `(not ,test-form)
|
|
763
|
+ test-form)
|
762
|
764
|
(push item res)))
|
763
|
765
|
res))
|
764
|
766
|
|
|
767
|
+(defmacro process-set (init-res invert-p)
|
|
768
|
+ `(let ((hashtable (list-to-hashtable list2 key test test-not)))
|
|
769
|
+ (if hashtable
|
|
770
|
+ (process-set-body ,init-res ,invert-p
|
|
771
|
+ (nth-value 1 (gethash (apply-key key item) hashtable)))
|
|
772
|
+ (process-set-body ,init-res ,invert-p
|
|
773
|
+ (with-set-keys (member (apply-key key item) list2))))))
|
|
774
|
+
|
765
|
775
|
;; Convert a list to a hashtable. The hashtable does not handle
|
766
|
776
|
;; duplicated values in the list. Returns the hashtable.
|
767
|
777
|
(defun list-to-hashtable (list key test test-not)
|
... |
... |
@@ -803,10 +813,7 @@ |
803
|
813
|
(declare (inline member))
|
804
|
814
|
(when (and testp notp)
|
805
|
815
|
(error (intl:gettext "Test and test-not both supplied.")))
|
806
|
|
- (let ((hashtable (list-to-hashtable list2 key test test-not)))
|
807
|
|
- (if hashtable
|
808
|
|
- (process-set list2 (not (nth-value 1 (gethash (apply-key key item) hashtable))))
|
809
|
|
- (process-set list2 (not (with-set-keys (member (apply-key key item) list2)))))))
|
|
816
|
+ (process-set list2 t))
|
810
|
817
|
|
811
|
818
|
|
812
|
819
|
(defun intersection (list1 list2 &key key
|
... |
... |
@@ -815,11 +822,7 @@ |
815
|
822
|
(declare (inline member))
|
816
|
823
|
(if (and testp notp)
|
817
|
824
|
(error "Test and test-not both supplied."))
|
818
|
|
- (let ((hashtable
|
819
|
|
- (list-to-hashtable list2 key test test-not)))
|
820
|
|
- (if hashtable
|
821
|
|
- (process-set nil (nth-value 1 (gethash (apply-key key item) hashtable)))
|
822
|
|
- (process-set nil (with-set-keys (member (apply-key key item) list2))))))
|
|
825
|
+ (process-set nil nil))
|
823
|
826
|
|
824
|
827
|
(defun set-difference (list1 list2 &key key (test #'eql testp) (test-not nil notp))
|
825
|
828
|
"Returns the elements of list1 which are not in list2."
|
... |
... |
@@ -830,11 +833,7 @@ |
830
|
833
|
(when (null list2)
|
831
|
834
|
(return-from set-difference list1))
|
832
|
835
|
|
833
|
|
- (let ((hashtable
|
834
|
|
- (list-to-hashtable list2 key test test-not)))
|
835
|
|
- (if hashtable
|
836
|
|
- (process-set nil (not (nth-value 1 (gethash (apply-key key item) hashtable))))
|
837
|
|
- (process-set nil (not (with-set-keys (member (apply-key key item) list2)))))))
|
|
836
|
+ (process-set nil t))
|
838
|
837
|
|
839
|
838
|
|
840
|
839
|
(declaim (end-block))
|