Lisp排序功能键

Kam*_*utu 3 lisp sorting key common-lisp nested-lists

我正在尝试排序看起来像这样的列表:

(defvar my-list '((:x 1 :y something) (:x 5 :y something) (:x 19 :y something)))
Run Code Online (Sandbox Code Playgroud)

我正在尝试按其中的值对其进行排序:x.我可以这样做

(sort my-list #'> :key #'second)
Run Code Online (Sandbox Code Playgroud)

但我更倾向于使用getf函数而不是second,但我无法弄清楚如何:x作为参数传递.

从我可以收集的东西#'getf回来(getf ((:x 1 :y something) '(:x 5 :y something) (:x 19 :y something)) [external].我将如何:x作为第二个参数传递?

我能想到的唯一方法是创建一个包装函数getf,它只将一个列表作为参数并:x默认传入.必须有更好的方法.

Rai*_*wig 8

如果在Lisp代码中使用属性作为键是常见的,那么您可以定义一个函数来创建键函数.见使用property-key-fn.

CL-USER 22 > (defparameter *my-list* (copy-list '((:x 1  :y foo)
                                                  (:x 5  :y bar)
                                                  (:x 19 :y baz))))
*MY-LIST*

CL-USER 23 > (defun property-key-fn (property)
               (lambda (plist)
                 (getf plist property)))
PROPERTY-KEY-FN

CL-USER 24 > (setf *my-list* (sort *my-list* #'> :key (property-key-fn :x)))
((:X 19 :Y BAZ) (:X 5 :Y BAR) (:X 1 :Y FOO))

CL-USER 25 > (setf *my-list* (sort *my-list* #'string> :key (property-key-fn :y)))
((:X 1 :Y FOO) (:X 19 :Y BAZ) (:X 5 :Y BAR))
Run Code Online (Sandbox Code Playgroud)


sds*_*sds 5

这不是比lambda以下更好的方式:

(defvar *my-list* '((:x 1 :y something) (:x 5 :y something) (:x 19 :y something)))
(sort *my-list* #'> :key (lambda (plist) (getf plist :x)))
==> ((:X 19 :Y SOMETHING) (:X 5 :Y SOMETHING) (:X 1 :Y SOMETHING))
Run Code Online (Sandbox Code Playgroud)

你可能正在寻找currying,但Common Lisp没有那个OOTB.

Rainer的回答提供了临时的讨论.

  • 以及带有[cl21](https://lispcookbook.github.io/cl-cookbook/cl21.html)的简短版本:`(sort * my-list *#'>:key ^(getf%:x))` :) (2认同)