[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Collecting data into a string.



The function string-append accepts any number of strings and appends them.
The apply function applies a function to all the argumets in a list, so
(apply string-append my-list-of-strings) appends them all.  You can write
a loop to build up a list of strings and then build one string at the end.
This way the code is functional, and it doesn't do O(n^2) work copying
the whole string (length O(n)) each time a little more is appended
(O(n) times).

The R5RS documentation available from help-desk or the help menu of
DrScheme describes string-set!, though its use often leads to poor style.

Good luck!

Paul

On Mon, Jul 09, 2001 at 02:27:01AM -0400, Jordan Katz wrote:
> Hi,
> 
>   I have a question regarding a piece of code which I've already
>   posted to this list before.  I have a loop which collects data that
>   needs to be set into a MrEd text-field% widget.  In order to set the
>   box to contain this data, I have to call the set-value method which
>   expects a single string.  My approach to solving this would be to
>   simply append all my data as I iterate through the loop into one
>   string and then pass that string to the procedure; I realize that
>   this may not be the Scheme/Functional way of doing this--it seems
>   rather procedural because it (as far as I understand) involves
>   declaring a variable before using it, so if you can think of a
>   cleaner way please let me know, but I tried implementing this as
>   described (there are other minor questions in the comments of the code):
> 
> ;;
> ;; This is my version of a string concatenation function.
> ;; I was *extremely* surprised to find that the MzScheme manual had
> ;; no function to concatenate strings.  If I overlooked it or if you
> ;; can think of a better way to write this one, let me know. 
> ;; 
> (define (string-concat str1 str2)
>   (let ((s-list1 (string->list str1))
>         (s-list2 (string->list str2)))
>     (list->string (append s-list1 s-list2))))
> 
> (define (grab-html b e)
>   (let*-values
>    (((url) (send urlbox get-value))
>     ((sin sout) (tcp-connect url 80))
>     ((html-start) (regexp "Content-Type:.*"))
>     ;;
>     ;; I thought I need to declare `html-src' as a string here so
>     ;; I can later use it to store all the values from the second
>     ;; do loop, and this was my way of doing it. 
>     ;;
>     ((html-src) (string)))
>    (fprintf sout "GET http://www.~a/ HTTP/1.0~n~n" url)
> 
>    ;; read until "Content-Type..." is met
>    (do ((line (read-line sin 'any) (read-line sin 'any)))
>        ((regexp-match html-start line)))
>    
>    (read-line sin 'any)
>    (read-line sin 'any)  ;; once more for the blank line
> 
>    ;; print the actual source
>    (do ((line (read-line sin 'any) (read-line sin 'any)))
>        ((eof-object? line))
>      ;;
>      ;; Why the hell isn't there documentation for string-set! ?
>      ;; 
>      (string-set! html-src (string-concat html-src line)))
> 
>    (printf "~a~n" html-src)))
> 
> Thanks a lot,
> -- 
> Jordan Katz <katz@underlevel.net>  |  Mind the gap