Question

I want to take an arbitrary list of lists and "rotate" it. That is, for a list of lists of size 3x3:

#lang racket
(require rackunit)

(define (rotate-lol lol)
  (append (list (map first lol)) (list (map second lol)) (list (map third lol))))

(check-equal? (rotate-lol (list (list 'a 'b 'c)
                                (list 'd 'e 'f)
                                (list 'g 'h 'i)))
          (list (list 'a 'd 'g)
                (list 'b 'e 'h)
                (list 'c 'f 'i)))

I'm thinking list-ref will replace first/second/third but I can't quite figure out the most concise way to do this.

I know there has got to be an elegant way to do this. I've done somewhat inelegant solutions to this problem in the past that were more domain specific, but I'd like to solve this for the general case, stash this in a personal library, and be done with the problem. Any tips or solutions?

Was it helpful?

Solution

It's pretty much like zip and you don't have to make it since it's already in the SRFI-1 list library:

(require srfi/1)
(zip '(a b c) '(d e f) '(g h I)) ; ==> ((a d g) (b e h) (c f i))

Now to get to take all parameters as a list you use apply:

(apply zip '((a b c) (d e f) (g h I)))
; ==> ((a d g) (b e h) (c f i))

And, just for completeness. Here is how zip is defined:

(define (zip . lsts)
  (apply map list lsts))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top