Floofk
Floofk

Reputation: 113

How to retrieve list of minimum values in each "column" from a list of lists?

So I have this little function that returns the minimal values in a set of 3 lists, is there a way I can write it to look much nicer? It doesn't seem very Lispy to me, but then again I probably don't know what that means (I'm a lisp noob) Any tips will be really appreciated.

;;;;minimum of 3

(defun minimum-of-3 (list1 list2 list3);returns the minimum value when comparing 3 lists
    (setq minimum-list '())
    (setq mini '())
    (loop for x in list1
            for y in list2
            for z in list3
            do
            (push x mini)
            (push y mini)
            (push z mini)
            (push (apply 'min mini) minimum-list)
            (setq mini '()))

    (reverse minimum-list))

Upvotes: 1

Views: 132

Answers (2)

Joshua Taylor
Joshua Taylor

Reputation: 85823

coredump's answer is fine, if you really want to use loop, but there's no need to here. mapcar can take multiple list arguments, and min takes one or more arguments, so you can just mapcar min over the lists.

(let ((xs '(8 4 1))
      (ys '(3 9 2))
      (zs '(9 2 4)))
  (mapcar 'min xs ys zs))
;=> (3 2 1)

Upvotes: 9

sheikh_anton
sheikh_anton

Reputation: 3452

If you already using loop you don't need anything else here, read about loop it's really powerfull

(defun minimum-of-3 (list-1 list-2 list-3)
  (loop :for x :in list-1
        :and y :in list-2
        :and z :in list-3
        :collect (min x y z)))

CL-USER> (minimum-of-3 '(1 2 3) '(4 5 6) '(7 8 -1))
(1 2 -1)
CL-USER> (minimum-of-3 '(1 2 3) '(4 -5 6) '(7 8 -1))
(1 -5 -1)
CL-USER> (minimum-of-3 '(1 2 3) '(4 -5 6) '(7 8))
(1 -5)

Upvotes: 4

Related Questions