LISP - `some` 函数
Lisp - some 序列谓词
Section titled “Lisp - some 序列谓词”some 函数是一个强大的序列谓词,用于确定一个或多个序列中是否至少有一个元素满足给定条件。它效率很高,因为一旦找到匹配项便会停止处理并返回。
(some predicate sequence &rest more-sequences)predicate:一个函数,接受与所提供序列数量相同的参数。对于匹配项,它应返回一个非nil值;否则返回nil。sequence:要迭代的第一个序列(列表、向量或字符串)。
返回值 - 关键特性
Section titled “返回值 - 关键特性”这非常重要:some 不仅仅返回 T(真)。它返回谓词返回的第一个非nil值。如果谓词在检查所有元素后从未返回非nil值,some 将返回 nil(假)。
示例 1:基本存在性检查
Section titled “示例 1:基本存在性检查”让我们检查一个列表是否包含任何偶数。
(let ((list1 '(1 3 5 8 9)) (list2 '(1 3 5 7 9)))
;; 谓词 `evenp` 对 8 返回 T。`some` 停止并返回 T。 (print (some #'evenp list1)) ;=> T
;; 没有元素满足 `evenp`,因此 `some` 返回 NIL。 (print (some #'evenp list2)) ;=> NIL)TNIL示例 2:利用返回值
Section titled “示例 2:利用返回值”在这里,我们将检查字符串中的第一个元音。谓词使用 member,它返回从找到的元素开始的子列表——一个非nil值。
(defun find-first-vowel (s) (some #'(lambda (char) (member char '(#\a #\e #\i #\o #\u))) s))
(let ((result1 (find-first-vowel "rhythm")) (result2 (find-first-vowel "lisp-is-fun")))
;; 没有元音,因此谓词始终返回 NIL。 (format t "Vowel found in 'rhythm': ~a~%" result1) ;=> NIL
;; 第一个元音是 'i'。`member` 返回 `(#\i #\o #\u)`。 ;; `some` 停止并返回此列表。 (format t "Vowel found in 'lisp-is-fun': ~a~%" result2) ;=> (#\I #\O #\U))Vowel found in 'rhythm': NILVowel found in 'lisp-is-fun': (#\I #\O #\U)示例 3:处理多个序列
Section titled “示例 3:处理多个序列”当你提供多个序列时,谓词在每一步都会从每个序列中接收一个元素。当最短的序列耗尽时,迭代停止。
;; 检查 list1 中是否有任何元素大于 list2 中的对应元素(let ((list-a '(1 5 3)) (list-b '(2 4 6)))
;; 1>2 为 nil。5>4 为 T。`some` 停止并返回 T。 (print (some #'> list-a list-b)) ;=> T)
(let ((list-c '(1 2 3)) (list-d '(4 5 6)))
;; 所有比较都返回 nil,所以最终结果是 NIL。 (print (some #'> list-c list-d)) ;=> NIL)TNILsome 非常适合简洁地表达“存在”或“至少一个”的条件:
- 验证:检查任何提交的数据字段是否包含无效字符。
(some #'invalid-char-p user-input) - 搜索:快速确定产品列表是否包含任何在售商品。
(some #'on-sale-p products) - 状态检查:在游戏中,检查列表中是否有任何敌人在攻击范围内。
(some #'in-range-p enemies)
相关谓词:every、notany、notevery
Section titled “相关谓词:every、notany、notevery”some 属于序列谓词家族的一部分:
some:是否存在至少一个真结果?every:是否所有结果都为真?notany:是否存在任何真结果?(是否所有结果都为假?)notevery:是否存在至少一个假结果?