给出两个由多个“对象”组成的列表,格式如下:(name id)
如何从第一个列表中获取与第二个名称不匹配的对象?
预期输出:
(remove-duplicates-by-name
'((Oliver 1) (Charlie 2) (Oscar 20))
'((Oliver 2)(Charlie 3)))
((Oscar 20))
(remove-duplicates-by-name
'((Oliver 1))
'((Oliver 2)(Charlie 3)))
()
(remove-duplicates-by-name
'()
'((Oliver 2)(Charlie 3)))
()
修改:
输出顺序很重要。示例:
(remove-duplicates-by-name
'((Oliver 1) (Charlie 2) (Oscar 20) (Daniel 30))
'((Oliver 2)(Charlie 3)))
正确的输出:((Oscar 20)(Daniel 30))
错误的输出:((Daniel 30)(Oscar 20))
答案 0 :(得分:3)
这是两个hacky解决方案。
(defun remove-duplicates-by-name (l to-remove)
;; low performance with large to-remove lists but fine with short
;; ones
(loop for e in l
unless (assoc (car e) to-remove)
collect e))
(defun remove-duplicates-by-name (l to-remove)
;; high performance with large to-remove lists but consy and
;; probably slow with short ones
(loop with dups = (loop with dt = (make-hash-table)
for e in to-remove
do (setf (gethash (car e) dt) t)
finally (return dt))
for e in l
unless (gethash (car e) dups)
collect e))
答案 1 :(得分:0)
您的示例与重复项无关,但所有相关事项 与Lists as Sets。
例如:
(set-difference '((Oliver 1) (Charlie 2) (Oscar 20)) '((Oliver 2)(Charlie 3)) :key #'car)
==> ((Oscar 20))
(set-difference '((Oliver 1)) '((Oliver 2)(Charlie 3)) :key #'car)
==> ()
(set-difference '() '((Oliver 2)(Charlie 3)) :key #'car)
==> ()