0

How would i define a function that takes in 2 lists(l1 l2) and returns the number of times an atom in list 1 occurs in list 2.

  • This question could help you get most of the way there: https://stackoverflow.com/questions/6050033/elegant-way-to-count-items – colelemonz Apr 23 '19 at 17:09

1 Answers1

0

The trick is to iterate over the second list, counting how many of the things you come across appear in the first. The member function lets you do that test, so you might end up with one of these two options:

;; A version with explicit recursion down the list
;;
;; This will blow its stack if list is too long.
(defun count-known-atoms (known list)
  "Return how many of the elements of `list' are atoms and appear
  in `known'."
  (if (null list)
      0
    (let ((hd (car list)))
      (+ (if (and (atom hd) (member hd known)) 1 0)
         (count-known-atoms known (cdr list))))))

;; A version using local variables and side effects. Less pretty, if you're a
;; fan of functional programming, but probably more efficient.
(defun count-known-atoms-1 (known list)
  "Return how many of the elements of `list' are atoms and appear
  in `known'."
  (let ((count 0))
    (dolist (x list count)
      (when (and (atom x) (member x known))
        (setq count (1+ count))))))

;; (count-known-atoms   '(1 2) '(0 1 2 3 4 5))    => 2
;; (count-known-atoms-1 '(1 2) '(0 1 '(2) 3 4 5)) => 1

If ELisp had a sum function to sum across a list or some sort of fold, another option would be to map across the second list to get zeros and ones and then squash them down afterwards. I don't think it does, though, so I'd suggest count-known-atoms-1.

Rupert Swarbrick
  • 2,793
  • 16
  • 26