BIGAL Posted May 17, 2019 Posted May 17, 2019 (edited) Hi every one, not often I aks a question I have a list of list's the inner lists can vary in the number of items, I need to make say a new list that will contain how many characters are in each say column of the master list. For below the correct answer is (15 2 4 5 2), this is part of a big program that I having been working on for months and just keeps getting bigger. The 1st item can be repeated multiple times just shortened this for suggestions. I dont necessarilly need code but rather a method, started doing repeats and whiles and just went round in circles. (setq lst (list (list "SETOUT_POINT_NO" "1") (list "SETOUT_POINT_NO" "2") (list "BLK01" "A" "B" "C") (list "BLK2" "D1" "C1" "B1" "A1") (list "BLK2" "D2" "C222" "B2" "A2") (list "BLK2" "e1" "e5" "f1111" "A1") ) ) Edited May 17, 2019 by BIGAL Quote
rlx Posted May 17, 2019 Posted May 17, 2019 (edited) having trouble with what you call the correct answer? your lst has 6 sub lists , the first being (list "SETOUT_POINT_NO" "1"). First string in list has 15 letters so that could explain the 15 in (15 2 4 5 2) , but this answer list has 5 numbers in it. I would have expected a list with 6 numbers? Are you just counting the characters from the first string in every list or the total number of characters from each list , but that doesn't seem to work because for the first sub list that then would be 15 + 1 = 16. Or if you're counting the number of times you have 15 characters in first string that would explain the 2 after the 15 , but the number of 4 characters ("BLK2") occurs 3 times and with 5 ("BLK01") occurs only once. So you explain the result list a little more please. I would have expected something like this : (defun tmp ( / lst res) (setq lst (list (list "SETOUT_POINT_NO" "1") (list "SETOUT_POINT_NO" "2") (list "BLK01" "A" "B" "C") (list "BLK2" "D1" "C1" "B1" "A1") (list "BLK2" "D2" "C222" "B2" "A2") (list "BLK2" "e1" "e5" "f1111" "A1") ) ) (foreach item lst (setq res (cons (strlen (car item)) res)) ) (reverse res) ) or (defun tmp2 ( / lst res) (setq lst (list (list "SETOUT_POINT_NO" "1") (list "SETOUT_POINT_NO" "2") (list "BLK01" "A" "B" "C") (list "BLK2" "D1" "C1" "B1" "A1") (list "BLK2" "D2" "C222" "B2" "A2") (list "BLK2" "e1" "e5" "f1111" "A1") ) ) (foreach item (reverse lst) (setq res (cons (apply '+ (mapcar 'strlen item)) res))) ) Edited May 17, 2019 by rlx Quote
dlanorh Posted May 17, 2019 Posted May 17, 2019 15 2 4 5 2 "SETOUT_POINT_NO" "1" "SETOUT_POINT_NO" "2" "BLK01" "A" "B" "C" "BLK2" "D1" "C1" "B1" "A1" "BLK2" "D2" "C222" "B2" "A2" "BLK2" "e1" "e5" "f1111" "A1" @rlx does this help Quote
rlx Posted May 17, 2019 Posted May 17, 2019 2 minutes ago, dlanorh said: 15 2 4 5 2 "SETOUT_POINT_NO" "1" "SETOUT_POINT_NO" "2" "BLK01" "A" "B" "C" "BLK2" "D1" "C1" "B1" "A1" "BLK2" "D2" "C222" "B2" "A2" "BLK2" "e1" "e5" "f1111" "A1" @rlx does this help ah, cross section... that makes sense Quote
Grrr Posted May 17, 2019 Posted May 17, 2019 (defun MaxNumCharsPerColumnForMatrixListOfStrings ( L ) ( '( ( f L ) (if L (f L))) '( ( L / a ) (cond ( (not L) L) ( (vl-consp (setq a (car L))) (cons (apply 'max (mapcar 'strlen a)) (f (cdr L))) ) ( (f (cdr L)) ) ) ) (apply 'mapcar (cons 'list ( '( ( L / i ) (setq i (apply 'max (mapcar 'length L))) (mapcar ''( (x) (while (< (length x) i) (setq x (append x '("")))) x) L) ) L ) ) ) ) ) _$ (MaxNumCharsPerColumnForMatrixListOfStrings '(("SETOUT_POINT_NO" "1") ("SETOUT_POINT_NO" "2") ("BLK01" "A" "B" "C") ("BLK2" "D1" "C1" "B1" "A1") ("BLK2" "D2" "C222" "B2" "A2") ("BLK2" "e1" "e5" "f1111" "A1") ) ) >> (15 2 4 5 2) Quote
rlx Posted May 17, 2019 Posted May 17, 2019 oh darn , you just beat me to it Grrr , but nice solution as always , I also did the appending thing but with zeros after I build a list with all the strlennies... Quote
Grrr Posted May 17, 2019 Posted May 17, 2019 10 minutes ago, rlx said: oh darn , you just beat me to it Grrr , but nice solution as always , I also did the appending thing but with zeros after I build a list with all the strlennies... Thanks, I haven't coded in a while (too much draftmans work). Anyway I feel bad for overwhelming Bigal with my crypted coding style, so heres simplified example of my previous reply: ;| Example (MakeEvenLengthSubItems) : (MakeEvenLengthSubItems '(("A1" "B1") ("A2") ("A3" "B3" "C3" "D3") ) ) >> '(("A1" "B1" "" "") ; Making the list 'rectangular', see in (Columns->Rows) why so ("A2" "" "" "") ("A3" "B3" "C3" "D3") ) |; (defun MakeEvenLengthSubItems ( L / SubListMaxLength itm nL ) (setq SubListMaxLength (apply 'max (mapcar 'length L))) (foreach itm L (while (< (length itm) SubListMaxLength) (setq itm (append itm '(""))) ) (setq nL (cons itm nL)) ) (reverse nL) ) ;| Example(s) (Columns->Rows): (Columns->Rows '(("A1" "B1") ("A2") ("A3" "B3" "C3" "D3") ) ) >> (("A1" "A2" "A3")) ; This means that if the subitems don't have even length, we won't get accurate results ;; However - (Columns->Rows (MakeEvenLengthSubItems '(("A1" "B1") ("A2") ("A3" "B3" "C3" "D3") ) ) ) >> '( ("A1" "A2" "A3") ; The result looks okay ("B1" "" "B3") ("" "" "C3") ("" "" "D3") ) |; (defun Columns->Rows ( L ) (apply 'mapcar (cons 'list L)) ; Lee Mac introduced this technique for manipulating matrix lists (lists of lists) ) ;| Example (LetsCount): (LetsCount ; - just process the above result in order to count the strlen's (Columns->Rows (MakeEvenLengthSubItems '(("SETOUT_POINT_NO" "1") ("SETOUT_POINT_NO" "2") ("BLK01" "A" "B" "C") ("BLK2" "D1" "C1" "B1" "A1") ("BLK2" "D2" "C222" "B2" "A2") ("BLK2" "e1" "e5" "f1111" "A1") ) ) ) ) >> (15 2 4 5 2) |; (defun LetsCount ( L / nL ) (foreach x L (setq nL (cons (apply 'max (mapcar 'strlen x)) nL)) ) (reverse nL) ) Quote
rlx Posted May 17, 2019 Posted May 17, 2019 (edited) mine isn't (wasn't haha) so sophisticated as yours Grrr (defun t3 ( ) (setq lst (list (list "SETOUT_POINT_NO" "1") (list "SETOUT_POINT_NO" "2") (list "BLK01" "A" "B" "C") (list "BLK2" "D1" "C1" "B1" "A1") (list "BLK2" "D2" "C222" "B2" "A2") (list "BLK2" "e1" "e5" "f1111" "A1"))) (setq max-len (apply 'max (mapcar 'length lst))) (setq len-lst (mapcar '(lambda (x) (mapcar 'strlen x)) lst)) (setq new-lst (mapcar '(lambda (x) (repeat (- max-len (length x))(setq x (append x '(0)))) x) len-lst)) (mapcar ''((x)(apply 'max x)) (apply 'mapcar (cons 'list new-lst))) ) awel , got bigger apps to slay anyway , big server migration on the way , all drawings with Xrefs have to be modified. But this time , I make sure all paths are removed. Wasn't possible before because of outdated viewer on site but now I should be able to use projectname variable etc... thanx for the programming lesson Grrr Mac , nah , Mac Grrr sounds better... Edited May 17, 2019 by rlx 1 Quote
Roy_043 Posted May 17, 2019 Posted May 17, 2019 (edited) (defun ColStrLen (lst / i len ret str ) (setq i 0) (while (progn (setq len -1) (foreach sub lst (if (and (setq str (nth i sub)) (> (strlen str) len) ) (setq len (strlen str)) ) ) (if (/= len -1) (setq ret (cons len ret) i (1+ i) ) ) ) ) (reverse ret) ) Edited May 19, 2019 by Roy_043 Changed the initial value of len from 0 to -1 to account for empty strings. Quote
BIGAL Posted May 17, 2019 Author Posted May 17, 2019 Thank you all for providing some answers, Dlanorh was right, I should have posted something like that to explain, it’s part of a smarter block count routine, it sets the size of table columns. For further info the width of the table must multiply the number by say the text size to provide a nice look. I will use it to resize the table when adding more blocks to an existing table. I will study them more for other uses. Its almost there tested on blocks with up to 22 attributes. Will be a pay for program but cheap. Quote
Lee Mac Posted May 25, 2019 Posted May 25, 2019 (edited) Late to the party - (defun cmaxstrlen ( l ) (if (apply 'or l) (cons (apply 'max (mapcar 'strlen (subst "" nil (mapcar 'car l)))) (cmaxstrlen (mapcar 'cdr l)) ) ) ) _$ (cmaxstrlen lst) (15 2 4 5 2) Edited May 25, 2019 by Lee Mac 1 Quote
rlx Posted May 25, 2019 Posted May 25, 2019 Not sure how much your boss is paying you Lee but its not nearly enough 1 Quote
pBe Posted May 26, 2019 Posted May 26, 2019 similar to LM (Defun _maxpercol_r (d / m n) (if d (cons (apply 'max (mapcar 'strlen (mapcar 'car d))) (_maxpercol_r (vl-remove-if 'null (mapcar 'cdr d)) ) ) ) ) Quote
BIGAL Posted May 27, 2019 Author Posted May 27, 2019 Thank you Lee and Pbe I will be getting back onto the project and this will help a lot. Screwed something up and my table columns are not sizing right so the code should fix that problem. For anyone infos a table column width its not actually the number of characters but + two margins and seems to reflect text height, so use a fuzzy textht+abit * strlen. That is the least of my debugging problems at this stage. But it is doing block counting with up to 5 levels of attributes. Tested on up to 22 attributes. Quote
pBe Posted May 27, 2019 Posted May 27, 2019 Suggest you use TEXTBOX to get both width and height. Quote
BIGAL Posted May 28, 2019 Author Posted May 28, 2019 Thanks pBe will try it just using a fuzzy method at moment. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.