Lisp排序功能键

时间:2017-07-24 14:11:23

标签: sorting key lisp common-lisp nested-lists

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

(defvar my-list '((:x 1 :y something) (:x 5 :y something) (:x 19 :y something)))

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

(sort my-list #'> :key #'second)

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

从我收集到的信息#'getf返回(getf ((:x 1 :y something) '(:x 5 :y something) (:x 19 :y something)) [external]。我如何将:x作为第二个参数传递?

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

2 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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))

您可能正在寻找currying,但Common Lisp没有OOTB。

Rainer的答案提供了临时的讨论。