是否有像 "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 中使用深度递归(参见 )。
我想使用 (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 中使用深度递归(参见