是否有像 "cl-every" 这样的 elisp 函数,在不等长的列表中 returns nil?

Is there an elisp function like "cl-every" that returns nil on lists of unequal length?

我想使用 (cl-every #'eq list1 list2) 在 elisp 中比较两个列表。但是,如果其中一个列表比另一个长,这可以 return t,我不希望这样。我可以在列表上调用 length,但随后我遍历每个列表两次,这是不必要的低效。是否有像 cl-every 这样的函数也检查相等的长度?

OOTB

我不认为有这样的功能OOTB。

自己动手

我认为实现一个并不难,只需修改cl-every

长度

请注意 length 是用 C 语言实现的,除非您的列表很大,否则不会显着影响性能:

(defun list-elements-eq (l1 l2)
  (and (= (length l1)
          (length l2))
       (every #'eq l1 l2)))

等于

您也可以将 equal 用于您的列表:因为 equal 从测试 eq 开始,它的关系将比您想要的要弱。

请注意,在 Common Lisp 中 equal 可能不会终止循环结构。 Emacs Lisp 是 "smarter":它检测圆度:

(setq x (list 1))
(setcdr x x)
(setq y (list 1))
(setcdr y y)
(eq x y)
(equal x y)
Debugger entered--Lisp error: (circular-list #1=(1 . #1#))
  equal(#1=(1 . #1#) #2=(1 . #2#))

(可以说,它应该 returns t 代替)。

普通 Lisp

一般来说,Common Lisp 是一种更好的语言"heavy lifting"。

如果你的列表很大,你可能想用它来代替 Emacs Lisp:

(defun list-elements-eq (l1 l2)
  (if (endp l1)
      (endp l2)
      (and (not (endp l2))
           (eq (pop l1) (pop l2))
           (list-elements-eq l1 l2))))

这是尾递归的,任何体面的 CL 都会优化递归(可能取决于 optimize 设置)。

您不想在 ELisp 中使用深度递归(参见 )。