Return elements if they are in two given lists in lisp

无人久伴 提交于 2019-12-25 09:40:32

问题


How can i return elements if they are in two given lists?

Example:

L1 = (a b c d e a b c)

L2 = (a d f g k c c)

Result = (a a a c c c c d d)

I want to remove elements that arent in both lists and, then, append the resultant lists


回答1:


You can start with a hash table, mapping a list element to a pair, first being elements from the first list, second - elements from the second. Then you collect the elements:

(defun common-elements (l1 l2 &key (test 'eql))
  (let ((ht (make-hash-table :test test)) ret)
    (dolist (e l1)
      (let ((pair (gethash e ht)))
        (if pair
            (push e (car pair))
            (setf (gethash e ht) (cons (list e) nil)))))
    (dolist (e l2)
      (let ((pair (gethash e ht)))
        (when pair ; no need to store e when it is not in l1
          (push e (cdr pair)))))
    (maphash (lambda (e pair)
               (declare (ignore e))
               (when (cdr pair) ; we know (car pair) is non-nil
                 (setq ret (nconc (car pair) (cdr pair) ret))))
             ht)
    ret))
(common-elements '(a b c d e a b c) '(a d f g k c c))
==> (A A A C C C C D D)

Note that the order in which the list elements are returned is not defined.



来源:https://stackoverflow.com/questions/44793126/return-elements-if-they-are-in-two-given-lists-in-lisp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!