2

Currently I'm using a fairly inefficient way to check if one list uses another list at it's end. Is there a more efficient way to do this?

(defun is-in-list (ls-haystack ls-ends-with) (catch 'found (while (not (or (eq ls-haystack t) (null ls-haystack))) (when (eq ls-haystack ls-ends-with) (throw 'found t)) (setq ls-haystack (cdr ls-haystack))))) 

2 Answers 2

6

What you are looking for is known in Common Lisp as tailp and is present in Emacs Lisp as cl-tailp:

(defun cl-tailp (sublist list) "Return true if SUBLIST is a tail of LIST." (while (and (consp list) (not (eq sublist list))) (setq list (cdr list))) (if (numberp sublist) (equal sublist list) (eq sublist list))) 
0

Use nthcdr:

(let* ((x '(4 5)) (y `(1 2 3 . ,x))) (eq (nthcdr (- (length y) (length x)) y) x)) ;; => t 
(defun foo (list list2) "Return t if LIST ends with LIST2." (eq (nthcdr (- (length list) (length list2)) list) list2)) (let ((x (list 4 5))) (foo (cons 1 (cons 2 x)) x)) ;; => t ;; it is ok if LIST is shorter than LIST2 (foo '(1 2) '(1 2 3 4)) ;; => nil 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.