Skip to content

LISP - `notany` 函数

notany 函数是一个序列谓词,用于判断给定测试对序列中的每个元素是否都为假。它是 some 函数的逻辑非。你可以将 notany 理解为在问:“是否存在不满足此条件的元素?”

(notany predicate sequence &rest more-sequences)
  • predicate: 一个函数指示器(例如,函数名或 lambda 函数),它接受与序列数量相等的参数。
  • sequence: 要测试的主序列。可以是列表、向量或字符串。
  • more-sequences: 可选的附加序列。如果提供,谓词必须接受的参数数量等于所有序列的总数量。

如果 predicate 对每个元素都返回 NIL(假),则返回 T(真)。如果 predicate 对任何元素返回非 NIL 值,notany 会立即停止并返回 NIL。

让我们检查一个列表是否包含偶数。

;; 谓词是 #'evenp。
;; 是不是没有元素是偶数?
;; 返回 T,因为列表中没有偶数。
(notany #'evenp '(1 3 5 7 9))
; => T
;; 返回 NIL,因为 2 是偶数,所以“没有元素是偶数”的条件为假。
(notany #'evenp '(1 2 3 5 7 9))
; => NIL

示例 2:使用 lambda 定义自定义谓词

Section titled “示例 2:使用 lambda 定义自定义谓词”

我们可以使用匿名 lambda 函数来执行自定义检查,例如查找是否有任何数字大于 10。

;; 谓词:检查数字是否大于 10 的 lambda。
(defvar *my-numbers* '(1 15 4 2))
;; 是不是没有数字大于 10?
;; 返回 NIL,因为 15 > 10。
(notany #'(lambda (x) (> x 10)) *my-numbers*)
; => NIL
;; 是不是没有数字大于 20?
;; 返回 T,因为所有数字都 <= 20。
(notany #'(lambda (x) (> x 20)) *my-numbers*)
; => T

序列也可以是字符串。这里,我们检查一个字符串是否包含任何数字字符。

;; 谓词 #'digit-char-p 检查字符是否是数字。
;; 是不是没有字符是数字?
;; 返回 T,因为字符串只包含字母。
(notany #'digit-char-p "TutorialsPoint")
; => T
;; 返回 NIL,因为 '1' 是数字。
(notany #'digit-char-p "Lisp-101")
; => NIL

当使用多个序列时,谓词必须接受来自每个序列的一个参数。

;; 谓词:#'>(大于)
;; 检查第一个列表中的任何元素是否大于
;; 第二个列表中对应的元素。
;; 是不是 list1 中没有元素大于 list2 中对应的元素?
;; 返回 NIL,因为 3 > 2。
(notany #'> '(1 2 3) '(4 1 2))
; => NIL
;; 返回 T,因为在每一对 (1 4), (2 5), (3 6) 中,第一个元素都不大于第二个元素。
(notany #'> '(1 2 3) '(4 5 6))
; => T
  • 数据验证:快速验证输入集合不包含任何无效值(例如,(notany #'is-invalid-p user-inputs))。
  • 状态验证:通过检查没有组件带有错误标志来确保系统处于安全状态(例如,(notany #'has-error-p *system-components*))。
  • 集合操作:检查两个集合是否不相交(没有共同元素)。
  • 调试提示:请记住,对空序列 () 使用 notany 总是返回 T,因为“谓词对某个元素为真”的条件永远不会被满足。