Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp sort function key

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.

like image 773
Kamarutu Avatar asked Dec 10 '22 10:12

Kamarutu


2 Answers

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))
like image 107
Rainer Joswig Avatar answered Dec 27 '22 14:12

Rainer Joswig


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.

like image 42
sds Avatar answered Dec 27 '22 16:12

sds