I'm trying to sort a list that looks something like this:
(defvar my-list '((:x 1 :y something) (:x 5 :y something) (:x 19 :y something)))
I'm trying to sort it by the value in :x
. I could do that like this
(sort my-list #'> :key #'second)
but I would very much prefer to use the getf
function instead of second
, but I can't figure out how to pass :x
as a parameter.
From what I can gather just #'getf
returns (getf ((:x 1 :y something) '(:x 5 :y something) (:x 19 :y something)) [external]
. How would I go about passing :x
as the second parameter?
The only way I could think of is to create a wrapper-function for getf
, which only takes a list as a parameter and passes in :x
by default. There must be a better way though.
If using a property as a key is common in your Lisp code, then you can define a function to create the key function. See the use of 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))
The is no better way than 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))
You might be looking for currying, but Common Lisp does not have that OOTB.
Rainer's answer offers ad hoc currying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With