How would I get the min/max of a list using a key
Asked Answered
E

2

7

I currently have a list of objects, each containing a certain attribute. I would like to get the element of the list with the min attribute value. Is there a concise way of doing this?

The python equivalent would be something like: min(d, key=d.get)

Is there a way of getting the min/max N elements?

Ethelyn answered 16/5, 2015 at 9:6 Comment(0)
M
11
CL-USER 8 > (reduce #'min '((1) (-1) (3)) :key #'first)
-1

or

CL-USER 9 > (loop for e in '((1) (-1) (3)) minimize (first e))
-1

I fear getting the container element is more difficult:

CL-USER 9 > (defun minimum (list predicate key)
              (when list
                (let* ((m0 (first list))
                       (m1 (funcall key m0)))
                  (mapc (lambda (e0 &aux (e1 (funcall key e0)))
                          (when (funcall predicate e1 m1)
                            (psetf m0 e0 m1 e1)))
                        list)
                  m0)))
MINIMUM

CL-USER 10 > (minimum '((a 1) (b -1) (c -2)) #'< #'second)
(C -2)

CL-USER 11 > (minimum '((a 1) (b -1)) #'< #'second)
(B -1)

CL-USER 12 > (minimum '((a 1)) #'< #'second)
(A 1)

CL-USER 13 > (minimum '() #'< #'second)
NIL
Mali answered 16/5, 2015 at 10:6 Comment(1)
This seems to return the element after applying the function specified by key, returning the attribute. Is there a way to return the entire element itself?Ethelyn
H
3

Use the function provided by the Alexandria library: extremum.

(extremum '((a 3) (b 1) (c 2)) #'< :key #'second)
=> (B 1)
Himes answered 7/6, 2015 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.