View Full Version : Matrix list
frisbee
2017-11-22, 11:39 PM
Given a list that represents a matrix array, with variable number of rows, and the possibility of variable number of columns, and each cell of the matrix contains a list. I would like to take the rows and make them columns, and the column into rows
“A” 1
“B” 2
“C” 3
“D” 4
“E” 5
“F” 6
to
"A" "B" "C" "D" "E" "F"
1 2 3 4 5 6
It is my thinking that the initial list is just one row and might look like this
'(("G06" "95") ("G07" "714") ("G08" "201") ("G09" "639") ("G11" "1134") ("G12"
"25") ("G14" "578") ("G15" "203") ("G16" "560") ("G17" "39") ("G18" "832")
("G20" "1517") ("G21" "115") ("G22" "246") ("G23" "11") ("G24" "103") ("G26"
"823") ("G27" "1161") ("G28" "117") ("G30" "122") ("G31" "429") ("G32" "202")
("G33" "101") ("G35" "94") ("G36" "194") ("G37" "576") ("G41" "368") ("G42"
"205") ("AG42A" "205") ("AG42AA" "299") ("AG42AAA" "1193") ("G43" "427") ("G47"
"435") ("G48" "205") ("G50" "205") ("G54" "205") ("G55" "622") ("G56" "205")
("G65" "209") ("G68" "257") ("G70" "888"))
then perhaps transform it into a 4 column list using the function
(defun BreakList (lst len opt / ls l i) ; opt, T= by division or nil=by length
(setq i 1 l '() len (if opt (/ (length lst) len) len))
(while lst
(setq l (append l (list(car lst))))
(if (zerop (rem i len))
(setq ls (cons l ls) l nil)
)
(setq i (1+ i) lst (cdr lst))
) ; end while
(if l
(append (reverse ls) (list l))
(reverse ls)
) ;_ end of if
)
Yields a list like
'((("G06" "95") ("G07" "714") ("G08" "201") ("G09" "639")) (("G11" "1134")
("G12" "25") ("G14" "578") ("G15" "203")) (("G16" "560") ("G17" "39") ("G18"
"832") ("G20" "1517")) (("G21" "115") ("G22" "246") ("G23" "11") ("G24" "103"))
(("G26" "823") ("G27" "1161") ("G28" "117") ("G30" "122")) (("G31" "429")
("G32" "202") ("G33" "101") ("G35" "94")) (("G36" "194") ("G37" "576") ("G41"
"368") ("G42" "205")) (("AG42A" "205") ("AG42AA" "299") ("AG42AAA" "1193")
("G43" "427")) (("G47" "435") ("G48" "205") ("G50" "205") ("G54" "205"))
(("G55" "622") ("G56" "205") ("G65" "209") ("G68" "257")) (("G70" "888")))
This list I need to make rows into columns.
If anyone has a simpler way of doing this from the initial list, I gladly welcome the code.
Basically, it is my intention to take a long list printed to screen of room numbers with SF info,
and print it to the screen in columns instead, with the numbers in order top to bottom by columns.
Thanks in advance
BIG-AL
2017-11-24, 11:42 PM
You could look into using the nth function this can be 2 levels deep and would allow a + or - aproach
(Nth (setq y (+ y 1))(nth (setq x (- x 1)) lst))
frisbee
2017-11-25, 03:57 PM
(progn
;; Given a long list, most likely sorted, I thought it would be very useful to have the
;; option to print to the screen multiple columns top to bottom by columns instead
;; of one long screen print that required scrolling multiple pages. It should be fairly
;; easy to modify the Output2File function to print your data to a *csv text file instead.
;;
;; I hope you find this code useful
(setq A-List '(("101" "368") ("105" "446") ("106" "193") ("107" "106")
("108" "266") ("110" "246") ("113" "106") ("114" "282") ("115" "106") ("116"
"857") ("116A" "86") ("117" "414") ("118" "41") ("119" "64") ("120" "968")
("122" "136") ("124" "631") ("126" "118") ("129" "9") ("130" "298") ("130A"
"105") ("131" "117") ("132" "225") ("133" "111") ("134" "138") ("134A" "10")
("135" "111") ("136" "232") ("137" "106") ("138" "319") ("138A" "135") ("138B"
"134") ("139" "97") ("140" "1080") ("141" "296") ("A141" "135") ("143" "98")
("144" "16") ("145" "108") ("146" "283") ("147" "360") ("149" "115") ("149A"
"87") ("150" "1003") ("153" "302") ("155" "597") ("160" "1003") ("161" "224")
("163" "145") ("165" "109") ("167" "100") ("170" "132") ("171" "317") ("172"
"153") ("174" "114") ("175" "269") ("176" "330") ("177" "262") ("177A" "194")
("178" "327")) )
(defun ColScreenPrint ( A-List NumCols / SortedCnt NumRows Col1 Col2 Col3 Col4 wL wR bsL bsR
item1L item1R item2L item2R item3L item3R item4L item4R i vpflg otsflg
Spcr1L Spcr1R Spcr2L Spcr2R Spcr3L Spcr3R Spcr4L Spcr4R wL wR s otsflg
BreakList output2file ;locally defined functions
)
;; ------------- Locally defined functions ---------------
(defun BreakList (lst len opt / ls l i) ; opt, T= by division or nil=by length
(setq i 1 l '() len (if opt (/ (length lst) len) len))
(while lst
(setq l (append l (list(car lst))))
(if (zerop (rem i len))
(setq ls (cons l ls) l nil)
)
(setq i (1+ i) lst (cdr lst))
) ; end while
(if l
(append (reverse ls) (list l))
(reverse ls)
) ;_ end of if
) ;end defun BreakList
;; ---------------
(defun Output2File ( / )
(princ "\n")
(princ "\nNo files created. Output2File function is")
(princ "\nsimply a placeholder function for writing data to files.")
)
;; ============= Main Program ===============
(if (progn (initget 0 "File Screen")(eq "Screen" (cond ((getkword "\nPrint to: File / <Screen>")) ("Screen"))) )
(progn
(setq SortedCnt (length A-List) )
(if (or (not NumCols) (not (and (>= NumCols 1) (<= NumCols 4))))
(progn
(if NumCols (princ "\nNumber of columns must be between 1 and 4."))
(initget 6 "1 2 3 4")
(setq NumCols (atoi (cond ((getkword "\nEnter number of columns \(1-4\) <4>: ")) ("4"))) )
) ;end progn
) ;end if
(if (= 0 (rem SortedCnt NumCols)) (setq NumRows (/ SortedCnt NumCols)) (setq NumRows (1+ (/ SortedCnt NumCols))) )
(setq A-List (BreakList A-List NumRows nil)) ;Subdivides the list into NumRows of separate lists
(setq Col1 (nth 0 A-List)
Col2 (nth 1 A-List)
Col3 (nth 2 A-List)
Col4 (nth 3 A-List)
)
(setq wL 7 wR 5 s " ") ; Change wL and wR to adjust width of blank cells
(setq bsL (repeat (1- wL) (setq s (strcat " " s))) ) ;blank room # cell
(setq bsR (repeat (1- wR) (setq s (strcat " " s))) ) ;blank sf cell
(princ "\n")
(princ "\n Room # | SF ")
(if (> NumCols 1) (princ "|| Room # | SF ") ) ;coordinate width of cells with wL and wR above
(if (> NumCols 2) (princ "|| Room # | SF ") ) ;coordinate width of cells with wL and wR above
(if (> NumCols 3) (princ "|| Room # | SF ") ) ;coordinate width of cells with wL and wR above
(princ "\n_________|_______") ;coordinate width of cells with wL and wR above
(if (> NumCols 1) (princ "||_________|_______") ) ;coordinate width of cells with wL and wR above
(if (> NumCols 2) (princ "||_________|_______") ) ;coordinate width of cells with wL and wR above
(if (> NumCols 3) (princ "||_________|_______") ) ;coordinate width of cells with wL and wR above
;; Preparing data for printing the output table
(repeat (length Col1)
;; This section sets the info for each cell for each double column
;; Mofify as necessary to suit your own needs
(setq item1L (caar Col1) item1R (cadar Col1) ) ;Col1 will always have data
(if (and Col2 (> NumCols 1)) (setq item2L (caar Col2) item2R (cadar Col2)) (setq item2L bsL item2R bsR) ) ;if Col2 is empty then blank spaces
(if (and Col3 (> NumCols 2)) (setq item3L (caar Col3) item3R (cadar Col3)) (setq item3L bsL item3R bsR) ) ;if Col3 is empty then blank spaces
(if (and Col4 (> NumCols 3)) (setq item4L (caar Col4) item4R (cadar Col4)) (setq item4L bsL item4R bsR) ) ;if Col4 is empty then blank spaces
;; This section sets the various spacer lengths for each cell in each column so the numbers are aligned neatly
(setq Spcr1L " " i (- wL (strlen item1L)) ) (repeat i (setq Spcr1L (strcat Spcr1L " ")) )
(setq Spcr1R " " i (- wR (strlen item1R)) ) (repeat i (setq Spcr1R (strcat Spcr1R " ")) )
(setq Spcr2L " " i (- wL (strlen item2L)) ) (repeat i (setq Spcr2L (strcat Spcr2L " ")) )
(setq Spcr2R " " i (- wR (strlen item2R)) ) (repeat i (setq Spcr2R (strcat Spcr2R " ")) )
(setq Spcr3L " " i (- wL (strlen item3L)) ) (repeat i (setq Spcr3L (strcat Spcr3L " ")) )
(setq Spcr3R " " i (- wR (strlen item3R)) ) (repeat i (setq Spcr3R (strcat Spcr3R " ")) )
(setq Spcr4L " " i (- wL (strlen item4L)) ) (repeat i (setq Spcr4L (strcat Spcr4L " ")) )
(setq Spcr4R " " i (- wR (strlen item4R)) ) (repeat i (setq Spcr4R (strcat Spcr4R " ")) )
;; Actually prints the data
(princ "\n ")
(princ (strcat item1L Spcr1L "|" Spcr1R item1R)) ;prints column 1 to the screen
(if (> NumCols 1) (princ (strcat " || " item2L Spcr2L "|" Spcr2R item2R)) ) ;prints column 1 to the screen
(if (> NumCols 2) (princ (strcat " || " item3L Spcr3L "|" Spcr3R item3R)) ) ;prints column 1 to the screen
(if (> NumCols 3) (princ (strcat " || " item4L Spcr4L "|" Spcr4R item4R)) ) ;prints column 1 to the screen
(setq Col1 (cdr Col1) Col2 (cdr Col2) Col3 (cdr Col3) Col4 (cdr Col4) )
) ;end repeat
(setq otsflg T) ;simply added to track if printed to screen so (textscr) can be called at the end of the program
) ;end progn
(Output2File)
) ;end if
(if otsflg (textscr))
(princ)
) ;end defun ColScreenPrint
(ColScreenPrint A-list 4)
) ;end progn
peter
2017-11-25, 05:17 PM
Given a list that represents a matrix array, with variable number of rows, and the possibility of variable number of columns, and each cell of the matrix contains a list. I would like to take the rows and make them columns, and the column into rows
“A” 1
“B” 2
“C” 3
“D” 4
“E” 5
“F” 6
to
"A" "B" "C" "D" "E" "F"
1 2 3 4 5 6
It is my thinking that the initial list is just one row and might look like this
(defun MatrixTranspose (lstMatrix)
(if (car lstMatrix)
(cons (mapcar 'car lstMatrix)
(MatrixTranspose (mapcar 'cdr lstMatrix))
)
)
)
(matrixtranspose (list (list "A" 1)(list "B" 2)(list "C" 3)))
returns
'(("A" "B" "C")(1 2 3))
P=
frisbee
2017-11-25, 08:00 PM
Thanks for this. I hate to admit this but mapcar is one of those functions I struggle to actually code.
How would it look if you had more than 2 elements in each initial sublist. It is my experience that rarely is it just two, often 3, 4, or more in a grouping.
peter
2017-11-26, 07:10 AM
Mapcar means multiple applications to the contents of the address register.
It means do this function to each member of this list (or these lists)
(mapcar 'strcase (list "a" "b" "c")) returns '("A" "B" "C")
(mapcar '+ (list 1 2 3)(list 0.1 0.2 0.3)) returns '(1.1 2.2 3.3)
Now for the scary one, mapcar lambda
(mapcar '(lambda (X Y)(+ X Y)) (list 1 2 3) (list 0.1 0.2 0.3)) returns '(1.1 2.2 3.3)
lambda is the same as defun except without a function name.
Oh and the matrix function is recursive, (that is why it is so elegant and short) and why it is difficult to understand.
It works with any matrix (as long as the initial lists are of equal length.
(matrixtranspose (list (list "A" 1 "a" )(list "B" 2 "b" )(list "C" 3 "c")))
returns
'(("A" "B" "C")(1 2 3)("a" "b" "c"))
P=
frisbee
2017-11-26, 01:01 PM
Thanks for the quick explanation, and I do have this basic understanding you explained for mapcar and lambda function, but still struggle to actually code it. But thanks for taking the time to explain. For me I can understand a function if shown, but to actually write and mapcar for myself, at this point I cant on my own.
Is there a way to use the nth function instead, and have nth vary depending on how many members are in the sub-lists? Basically, if the sub-list if 4 members long then it will know to do it for all four members, or if five, will do it for all five, and so on.
peter
2017-11-26, 08:12 PM
; intItems is the number of items in a sublist
; lstValues is the list to be parsed
(defun NthParse (intItems lstValues / lstSublist lstValues2)
(repeat (fix (/ (length lstValues) intItems))
(setq lstSublist nil)
(repeat intItems
(setq lstSublist (cons (car lstValues) lstSublist))
(setq lstValues (cdr lstvalues))
)
(setq lstValues2 (cons (reverse lstSublist) lstValues2))
)
(reverse lstValues2)
)
This will parse the list of values.
Not much different than your example.
Also if you use the go advanced button below the post edit window you can use the # symbols to put code tags around your code so it is formatted like mine above.
Then use the matrix transpose
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.