比较多个元素

许多

因此,我想比较来自四个不同列表的四个不同元素。像下面这样的例子,问题是等于应该只接受2个参数,是否有任何函数可以比较2个以上的元素?

(equal (nth 0 '(1 2 3)) (nth 0 '(1 2 3)) (nth 0 '(1 2 3)) (nth 0 '(1 2 3)))
约书亚·泰勒(Joshua Taylor)

有什么功能可以比较两个以上的元素?

Common Lisp中的许多比较函数都接受两个以上的参数。例如,所有=,/ =,<,>,<=,> =均可接受任意数量的参数,这意味着您可以执行

(= (nth 0 '(1 2 3))
   (nth 0 '(1 2 3))
   (nth 0 '(1 2 3))
   (nth 0 '(1 2 3)))

如果您需要equal(而不是=的特定行为,那么您将需要coredump提出的方法由于相等性是可传递的,因此您可以检查每个元素是否等于第一个元素(或列表为空):

(defun equal* (&rest arguments)
  (or (endp arguments)
      (let ((x (first arguments)))
        (every (lambda (y)
                 (equal x y))
               (rest arguments)))))

(equal* 1 1 1 1)
;=> T

实际上,因为你可以调用第一休息用的空列表,你甚至可以摆脱第一种情况,因为每一个在传递一个空列表将返回true:

(defun equal* (&rest arguments &aux (x (first arguments)))
  (every (lambda (y)
           (equal x y))
         (rest arguments)))

之后,由于这可能是常见的模式,因此您可以定义一个宏来为您定义这些:

(defmacro def-n-ary-equality (name predicate &rest args)
  (let ((arguments (gensym (string '#:arguments-)))
        (x (gensym (string '#:x-)))
        (y (gensym (string '#:y-))))
    `(defun ,name (&rest ,arguments &aux (,x (first ,arguments)))
       (every (lambda (y)
                (,predicate ,x ,y ,@args))
              (rest ,arguments)))))

(def-n-ary-equality equal* equal)
; ==
(DEFUN EQUAL* (&REST #:ARGUMENTS-1005 &AUX (#:X-1006 (FIRST #:ARGUMENTS-1005)))
  (EVERY (LAMBDA (Y)
           (EQUAL #:X-1006 #:Y-1007))
         (REST #:ARGUMENTS-1005)))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章