Author Topic: Delimited string to list, what goes wrong with my code ?  (Read 1301 times)

0 Members and 1 Guest are viewing this topic.

drawdraw

  • Mosquito
  • Posts: 14
Delimited string to list, what goes wrong with my code ?
« on: November 27, 2020, 02:03:29 AM »
Code - Auto/Visual Lisp: [Select]
  1. (setq s "3*3000,2500,2*2000")
  2.   (setq lst '() lst2 '())
  3.   (setq lst (LM:str->lst s ","))
  4.   (mapcar '(lambda (x)
  5.              (if (setq pos (vl-string-search "*" x))
  6.                (progn
  7.                  (setq num (substr x 1 pos))
  8.                  (setq d (substr x (+ 2 pos)))
  9.                  (repeat (atoi num)
  10.                    (setq lst2 (cons d lst2))
  11.                  )
  12.                )                        ;end progn
  13.                (setq lst2 (cons x lst2))
  14.              )                          ;end if
  15.            )
  16.           lst
  17.   )
  18.  
  19. ;by Lee Mac
  20. (defun LM:str->lst ( str del / pos )
  21.     (if (setq pos (vl-string-search del str))
  22.         (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
  23.         (list str)
  24.     )
  25. )
  26.  
  27.  

I want to make a string "3*3000,2500,2*2000" become a list (3000 3000 3000 2500 2000 2000).
I wrote the above code, but get the result: (("3000" "3000" "3000") ("2500" "3000" "3000" "3000") ("2000" "2000" "2500" "3000" "3000" "3000"))
Anyone can help me edit my code, so that it only get the result I wanted ?

Tharwat

  • Swamp Rat
  • Posts: 707
  • Hypersensitive
Re: Delimited string to list, what goes wrong with my code ?
« Reply #1 on: November 27, 2020, 02:49:00 AM »
Code - Auto/Visual Lisp: [Select]
  1. (setq s "3*3000,2500,2*2000")
  2.  
  3. (setq n (vl-list->string (mapcar '(lambda (x) (if (< 47 x 58) x 32)) (vl-string->list s))))
  4.  
  5.   (setq l (cons (substr (strcat (substr n 1 f) "000") 1 4) l)
  6.         n (substr n (+ 2 f))
  7.   )
  8. )
  9.  
  10.  

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Delimited string to list, what goes wrong with my code ?
« Reply #2 on: November 27, 2020, 05:03:05 AM »
You are very close: you just need to declare the list that you are building within the lambda function as local to the lambda function so that the value it holds is reset for every item in the list supplied to mapcar, and then apply the append function to the result in order to acquire a single list.

For example:
Code - Auto/Visual Lisp: [Select]
  1. (defun myfunction ( str )
  2.     (apply 'append
  3.         (mapcar
  4.            '(lambda ( itm / num pos tmp )
  5.                 (if (setq pos (vl-string-search "*" itm))
  6.                     (progn
  7.                         (setq num (substr itm (+ 2 pos)))
  8.                         (repeat (atoi (substr itm 1 pos))
  9.                             (setq tmp (cons num tmp))
  10.                         )
  11.                     )
  12.                     (list itm)
  13.                 )
  14.             )
  15.             (LM:str->lst str ",")
  16.         )
  17.     )
  18. )

Stefan

  • Bull Frog
  • Posts: 319
  • The most I miss IRL is the Undo button
Re: Delimited string to list, what goes wrong with my code ?
« Reply #3 on: November 27, 2020, 06:48:35 AM »
One solution is to use foreach instead.
The next code is just a fix for the code you posted
Code - Auto/Visual Lisp: [Select]
  1. (setq s "3*3000,2500,2*2000")
  2.   (setq lst '() lst2 '())
  3.   (setq lst (LM:str->lst s ","))
  4.   (foreach x lst
  5.              (if (setq pos (vl-string-search "*" x))
  6.                (progn
  7.                  (setq num (substr x 1 pos))
  8.                  (setq d (substr x (+ 2 pos)))
  9.                  (repeat (atoi num)
  10.                    (setq lst2 (cons d lst2))
  11.                  )
  12.                )                        ;end progn
  13.                (setq lst2 (cons x lst2))
  14.              )                          ;end if
  15.   )
  16. (reverse lst2)

Another solution, using LM:str->lst twice
Code - Auto/Visual Lisp: [Select]
  1.   (mapcar
  2.    '(lambda (x / l)
  3.       (setq x (LM:str->lst x "*"))
  4.       (mapcar 'atoi;atof?
  5.         (cond
  6.           ( (cdr x)
  7.             (repeat (atoi (car x))
  8.               (setq l (cons (cadr x) l))
  9.             )
  10.           )
  11.           (x)
  12.         )
  13.       )
  14.     )
  15.     (LM:str->lst s ",")
  16.   )
  17. )

drawdraw

  • Mosquito
  • Posts: 14
Re: Delimited string to list, what goes wrong with my code ?
« Reply #4 on: November 29, 2020, 07:16:33 PM »
Thank you very much for all replies !  :smitten: :smitten: :smitten:

Tqvm Lee Mac, now I realised that I should not use (setq lst2 (cons x lst2)) (in line 13), and then add apply 'append. And you show me to reduce the use of variable.

After many times trying, I found a simpler way using foreach:

Code - Auto/Visual Lisp: [Select]
  1. (defun ds2lst (s / x pos d lst)
  2.   (foreach x (LM:str->lst s ",")
  3.     (if (setq pos (vl-string-search "*" x))
  4.       (progn
  5.         (setq d (substr x (+ 2 pos)))
  6.         (repeat (atoi (substr x 1 pos))
  7.           (setq lst (cons d lst))
  8.         )
  9.       )                        
  10.       (setq lst (cons x lst))
  11.     )
  12.   )
  13.   (setq lst (reverse lst))
  14.   )
  15. (ds2lst "3*3000,2500,2*2000")
  16. ;("3000" "3000" "3000" "2500" "2000" "2000")
  17.  
« Last Edit: November 29, 2020, 09:09:14 PM by drawdraw »