Transposing lists in Common Lisp

后端 未结 1 707
眼角桃花
眼角桃花 2020-12-10 04:37

I am trying to transpose a list of lists; my comments indicate the thought process.

(setq thingie  \'((1 2 3) (4 5 6) (7 8 9)))  ;;test case

(defun trans (m         


        
相关标签:
1条回答
  • 2020-12-10 05:02

    There is a simple way for this:

    (defun rotate (list-of-lists)
      (apply #'mapcar #'list list-of-lists))
    

    Your attempt is always returning the original mat. Fix your indentation, and you see that the returned value from the if form is always thrown away.

    Edit: How this works:

    • List takes any number of arguments and makes a list of it. Its function definition can be imagined about like this:

      (defun list (&rest arguments)
        arguments) ; exploit the automatic &rest construction
      
    • Mapcar takes a function and any number of lists, and then makes a new list of the values created by calling the function always with one element from those lists. Example: (mapcar #'foo '((A B) (C D))) will construct a new list, where the first element is the result of (foo 'A 'C) and the second the result of (foo 'B 'D).

    • Apply takes a spreadable argument list designator as its last argument. This means that if you give it a list as its last argument, that list can be "spread" to produce individual arguments for the function. Example: (apply #'+ '(1 2 3)) has the same effect as (+ 1 2 3).

    Now you can expand the line:

    (apply #'mapcar #'list '((A B) (C D)))
    

    =>

    (mapcar #'list '(A B) '(C D))
    

    =>

    (list (list 'A 'C) (list 'B 'D))
    

    =>

    '((A C) (B D))
    
    0 讨论(0)
提交回复
热议问题