Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

String to List - most efficient way

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
Anonymous
978 Views, 10 Replies

String to List - most efficient way

Hey everyone,

 

I am trying to convert a string, such as "AAAA,BBBB,CCCC,DDDD,EEEE" into a list using the commas as a delimiter.  I have been using the following code (not written by me):

;----------------------------------------------------------------------
;
;  STR-2-LIST
;    SRC   source string
;    DLM   delimiter
;
(defun STR-2-LIST (SRC DLM)
  (read
    (strcat
      "(" (chr 34)
      (STRREPL-ALL SRC DLM (strcat (chr 34) " " (chr 34)))
      (chr 34) ")")))
;
;;---------------------------------------------------------------------
;RC   String to search
;SRCH  String pattern to find
;
(defun STRFIND (SRC SRCH / CNT RET)
  (setq CNT 1)
  (while (<= CNT (strlen SRC))
     (if
        (= (substr SRC CNT (strlen SRCH)) SRCH)
            (setq RET (list
                        (substr SRC 1 (1- CNT))
                        (substr SRC (+ CNT (strlen SRCH))))
                  CNT (1+ (strlen SRC)))
            (setq CNT (1+ CNT))))
  (if (null RET) (list SRC nil) RET))
;----------------------------------------------------------------------
;
;  STRREPL
;    SRC   source string
;    SRCH  string to find
;    SREP  replacement string
;
(defun STRREPL (SRC SRCH SREP / TMP)
   (setq TMP (STRFIND SRC SRCH))
   (if (not (null (cadr TMP))) (strcat (car TMP) SREP (cadr TMP)) SRC))
;----------------------------------------------------------------------
;
;  STRREPL-ALL
;    SRC   source string
;    SRCH  string to find
;    SREP  replacement string
;
(defun STRREPL-ALL (SRC SRCH SREP)
  (while (/= SRC (setq SRC (STRREPL SRC SRCH SREP))))
  SRC)


 

This works fine for small lists, but some lists I am working with can contain 1500 entries which can take over 10 seconds for the above code to convert from the string to a list.  This time really starts to add up (and become annoying) when you have to run this command many times in succession.

 

Does anyone have any ideas for alternate code that is less demanding on the computer?

 

Thanks as always for your help,

Chris

10 REPLIES 10
Message 2 of 11
Hallex
in reply to: Anonymous

;;author unknown
(defun strtolst (str del)  
  (if (setq pos (vl-string-search del str))
    (cons (substr str 1 pos)
          strtolst (substr str (+ pos 1 (strlen del))) del))
    (list str)
)
)

 ~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 3 of 11
kdub_nz
in reply to: Hallex

 

hallex, that doesn't seem correct. 

Perhaps sometging like this will suit : 

(defun CSVString->List (str del / i lst)
  (while (setq i (vl-string-search del str 0))
    (setq lst (cons (substr str 1 i) lst)
          str (substr str (+ i 1 (strlen del)))
    )
  )
  (reverse (cons str lst))
)

 

 


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 4 of 11
Hallex
in reply to: kdub_nz

Oops, missed the open parenthesis, sorry Smiley Surprised

This should work

(defun strtolst (str del)  
  (if (setq pos (vl-string-search del str))
    (cons (substr str 1 pos)
          (strtolst (substr str (+ pos 1 (strlen del))) del))
    (list str)
)
)

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 5 of 11
Kent1Cooper
in reply to: Anonymous

Some other ways of doing it:

 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/String-to-List/m-p/1064938/highlight/...

 

And a Search will reveal other similar threads.

Kent Cooper, AIA
Message 6 of 11
Anonymous
in reply to: Hallex

Great, thanks guys, that works so much better!

 

Cheers,

Chris

Message 7 of 11
Anonymous
in reply to: Hallex

Why does your code call (strlen del) numerous times even though the result is constant?

Message 8 of 11
Anonymous
in reply to: Anonymous

This might be faster on larger strings:

 

(defun string-to-list (s)
   (read
      (strcat 
         "(\""
         (vl-list->string
            (apply 'append
               (subst 
                  '(34 34) 
                  '(44) 
                  (mapcar 'list (vl-string->list s))
               )
            )
         )
         "\")"
      )
   )
)

 

Message 9 of 11
_gile
in reply to: Anonymous

Hi Tony,

 

If I'm not the author of this routine, I wrote a very similar one (called str2lst with others variables names).

 

I agree (strlen del) is contant, but as the routine uses a recursive process in which the expression is evaluated at each recursive call, I thaught unusefull to stroe the value in a variable.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 of 11
Kent1Cooper
in reply to: Anonymous

Another way [not better, not shorter, but not much longer than some others] that it occurred to me that this can be done, as long as the delimiter is a single character:

 

(defun StrToList (s d / c w r)
  (setq w "")
  (while (> (strlen s) 0)
    (if (/= (setq c (substr s 1 1)) d)
      (setq w (strcat w c))
      (setq r (cons w r) w "")
    )
    (setq s (substr s 2))
  )
  (reverse (cons w r))
)
 

[The s is for string, d for delimiter, c for character, w for word, r for result.]

 

It steps through the string, and if the next character is not the delimiter, it adds it to the word it is building, but if it is the delimiter, it adds the word it has built so far to the result list.  When it gets to the end, it adds the last word it has built, in the process of reversing the list.

Kent Cooper, AIA
Message 11 of 11
Anonymous
in reply to: Kent1Cooper

If the quest was for the most efficent way, then using an approach

involving a (strcat) for each character added to each string would not

be terribly efficient, because each (strcat) must create a copy of the

original string, which generates a lot of garbage. Of course it wouldn't

matter much in cases where the strings being built are small, or there

there are not very many of them, but in other cases, depending mainly

on the number of calls to (strcat), it could be noticable.

 

Have a look at this:

 

    http://www.caddzone.com/StringBuildingTest.lsp

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost