gpt4 book ai didi

lisp - 使用带有 &key 参数的 remove-if-not

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:26 24 4
gpt4 key购买 nike

我有以下代码,它应该是一个高阶函数,它根据输入的 &key 参数过滤元素(在本例中为 :year, :month:type

   (defun filter-by (&key year month type)
"Remove members of the list not matching the given year and/or month and/or type, returns a
function that takes the list"
(lambda (lst)
(remove-if-not #'(lambda (element)
(when year
(equalp (local-time:timestamp-year (get-record-date element))
year)))
(when month
(equalp (local-time:timestamp-month (get-record-date element))
month)))
(when type
(equalp (get-type element)
type))))
lst)))

问题是,除非使用 all 关键字参数,否则它将始终返回 nil,我猜是因为 when 表单在 remove-if-not 内运行。

有没有办法在不诉诸多个 cond 语句的情况下完成这项工作? cond 的问题是我必须特别地写下所有可能使用的参数组合,这对于 3 个参数是可以的,但如果将来我想使用其他关键字进行过滤。

最佳答案

Common Lisp 的关键字参数有一个特殊的语法,可以让你告诉是否提供了参数。我认为你应该能够使用这是为了完成你想要的。

这是一个工作示例,尽管数据表示略有不同因为我没有你对 local-timeget-record-date 的定义。你应该能够轻松地使其适应您的代码。

(defun my-filter-by (lst &key
(year nil year-p) ;; nil is the default
(month nil month-p) ;; year-p/month-p/day-p say whether
(day nil day-p)) ;; the argument was supplied
(remove-if-not
(lambda (element)
(let* ((year-okp (or (not year-p)
(equal year (cdr (assoc :year element)))))
(month-okp (or (not month-p)
(equal month (cdr (assoc :month element)))))
(day-okp (or (not day-p)
(equal day (cdr (assoc :day element)))))
(all-okp (and year-okp month-okp day-okp)))
all-okp))
lst))

还有一些例子:

(defparameter *lst* '(((:year . 2000) (:month . :may) (:day . 17))
((:year . 2000) (:month . :may) (:day . 18))
((:year . 2001) (:month . :aug) (:day . 2))
((:year . 2002) (:month . :jan) (:day . 5))))


(my-filter-by *lst*) ;; keeps everything
(my-filter-by *lst* :year 2000) ;; everything from 2000
(my-filter-by *lst* :year 2000 :day 17) ;; only 2000 / may 17

关于lisp - 使用带有 &key 参数的 remove-if-not,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27881709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com