Convert Comma delimited string to List

Convert Comma delimited string to List

saifumk8
Advocate Advocate
3,206 Views
6 Replies
Message 1 of 7

Convert Comma delimited string to List

saifumk8
Advocate
Advocate

I need to convert string as a list in Lisp.

 

I have this:

"1000,1947958.861,1165020.235,588.929,B BOC"

I need like this

(1000 1947958.861 1165020.235 588.929 B BOC)

 

Thanks for advance. 

0 Likes
Accepted solutions (2)
3,207 Views
6 Replies
Replies (6)
Message 2 of 7

doaiena
Collaborator
Collaborator
Message 3 of 7

phanaem
Collaborator
Collaborator
Accepted solution
_$ (setq str "1000,1947958.861,1165020.235,588.929,B BOC")
"1000,1947958.861,1165020.235,588.929,B BOC"
_$ (read (strcat "(" (vl-string-translate "," " " str) ")"))
(1000 1.94796e+06 1.16502e+06 588.929 B BOC)
Message 4 of 7

saifumk8
Advocate
Advocate

Thank you very much, it's working.

0 Likes
Message 5 of 7

hak_vz
Advisor
Advisor

OK. Let we see which proposed solution produces correct result.

 

@saifumk8asked for:


I need to convert string as a list in Lisp.

I have this:

"1000,1947958.861,1165020.235,588.929,B BOC"

I need like this

(1000 1947958.861 1165020.235 588.929 B BOC)


@doaiena  proposed using Lee Mac's http://www.lee-mac.com/stringtolist.html 

 

Applied to test string it produces:

(LM:str->lst str "," ) 
("1000" "1947958.861" "1165020.235" "588.929" "B BOC")

It just have to be translated to meaningful data type.

 

Here using "read" my create an error

(mapcar 'read (LM:str->lst str "," ))
(1000 1.94796e+006 1.16502e+006 588.929 B)

@phanaem  proposed

(read (strcat "(" (vl-string-translate "," " " str) ")"))
(1000 1.94796e+06 1.16502e+06 588.929 B BOC)

It is a solution to what @saifumk8  asked, but question is what is a final string in a list "B BOM" or "BOM".

 

So here is my solution that takes into account data type of particular list element.

(defun read_to_lst (str delimiter clear_spaces / ret poz *error*)
;converts delimited string into a list and respects data types
;hak_vz (24.11.2019)
;if string includes unwanted empty spaces, they can be cleared by setting switch "clear_spaces" to true
;this option may occur when reading strings from file or manually prepared data set
    
    (defun *error* ( ) (princ "\nThere was some error") (princ))
    (defun clear_empty_spaces (str)
        (setq str (vl-string-trim " " str))
        (while (vl-string-search " " str)(setq str (vl-string-subst "" " " str)))
        str
    )
    (if clear_spaces (setq str (clear_empty_spaces str))) 
    (setq poz 0)
    (while (and str (>  (strlen str) 0) (numberp poz))
    (setq poz (vl-string-position (ascii delimiter) str))
    (if (and str (> (strlen str) 0))
       (cond ((and (numberp poz)(>= poz 0))(setq ret (cons (substr str 1 poz) ret) str (substr str (+ poz 2))))
             (T (setq ret (cons str  ret) str nil))
        )
    )
    )
    (mapcar '(lambda (x) (if (numberp (read x)) (setq x (read x)) x))(reverse ret))
)
(princ "\nFunction READ_TO_LST converts delimited string into a list.")
(princ "\nUsage example: (read_to_list str \",\" nil) or any applicable string delimiter.") 
(princ)
Command: (setq str "1000,1947958.861,1165020.235,588.929,B BOC")
"1000,1947958.861,1165020.235,588.929,B BOC"
Command: (read_to_lst str "," nil)
(1000 1.94796e+006 1.16502e+006 588.929 "B BOC")

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 6 of 7

saifumk8
Advocate
Advocate
Accepted solution

Thank you for your reply, I have solved the issue as below.

 

(setq Lst1 (read (strcat "(" (vl-string-translate "," " " Ln1) ")")) )

(setq Px (cadr Lst1) )

(setq Py (caddr Lst1))

(setq Lst2 (mapcar 'vl-princ-to-string Lst1))


(setq PdLn (length Lst2))

(cond
(
(= PdLn 5) (Setq Pd (nth 4 Lst2) )
)

(
(= PdLn 6) (Setq Pd (strcat (nth 4 Lst2) " " (nth 5 Lst2) ) )
)

(
(= PdLn 7) (Setq Pd (strcat (nth 4 Lst2) " " (nth 5 Lst2) " " (nth 6 Lst2)) )
)

(t (Setq Pd (strcat (nth 4 Lst2) " " (nth 5 Lst2) " " (nth 6 Lst2)) ) )

 

0 Likes
Message 7 of 7

hak_vz
Advisor
Advisor

If that solution suites you then I agree with you. Self written code that works is best code, no mater how simple or complicated.

 

Your solution is ok for this particular set, but situation complicates if number of data in list rises, and using strcat become to complicated and asks for to many cond statements.

If your data are correctly separated by delimiter, then after splitting string into a list, you may simply use something like:

 

(mapcar 'set '(px py pd)  '(1250.25 2525.25 "B BOM"))

It assigns value 1250.25 to px and so on.  In a function you just have to make this variable names local.

 

If we apply  Lee Mac's str_to_lst that @doaiena proposed then for example

(setq str "1e3,2500.25,Over the moon")

(defun str_to_lst (str / len lst pos )
    (setq len (1+ (strlen ",")))
    (while (setq pos (vl-string-search "," str))
        (setq lst (cons (substr str 1 pos) lst)
              str (substr str (+ pos len))
        )
    )
    (reverse (cons str lst))
)
(setq lst (mapcar '(lambda (x) (if (numberp (read x)) (setq x (read x)) x)) (str_to_lst str)))

It produces a list lst

(1000.0 2500.25 "Over the moon")

And then simply

(mapcar 'set '(px py pd) lst)

If number of vars change you just have to change variable sequence. And you have a universal solution that works for any data set written as a string (as red from a file or ...).

 

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes