12

For example I have (list "a" "1" "b" "2" "c" "3").

Now I want to turn this list into one "a1b2c3".

How do I do that?

Thank you.

3 Answers 3

12

(apply string-append (list "a" "1" "b" "2" "c" "3")) or (string-append* "" (list "a" "1" "b" "2" "c" "3")) should work. See: http://docs.racket-lang.org/reference/strings.html

If you wanted a procedure to do this you can just write (define (strings->string sts) (apply string-append sts))

Sign up to request clarification or add additional context in comments.

2 Comments

This is perfectly fine when you know you will be joining only a small number of strings. More generally, apply-based techniques make an argument list out of their input so they may hit the argument list length limit of the language implementation if they are given a long list. The limit is not very high in some language standards/implementations; not sure what is the situation with Scheme/Racket.
In Racket you don't have this problem, it's safe to use the apply technique, even for long lists.
11

Don't reinvent the wheel! in Racket, there exists one procedure specifically for this and its' called string-join:

(string-join '("a" "1" "b" "2" "c" "3") "")
=> "a1b2c3"

Quoting the documentation:

(string-join strs                
             [sep                
              #:before-first before-first                
              #:before-last before-last              
              #:after-last after-last]) → string?

strs : (listof string?)
sep : string? = " "
before-first : string? = ""
before-last : string? = sep
after-last : string? = ""

Appends the strings in strs, inserting sep between each pair of strings in strs. before-last, before-first, and after-last are analogous to the inputs of add-between: they specify an alternate separator between the last two strings, a prefix string, and a suffix string respectively.

1 Comment

This is also implemented in Guile.
5

For what it's worth, here are some implementations with and without a delimiter (i.e. a string that is inserted between each pair of strings, such as a space or a comma).

The functions fold and fold-right are from SRFI 1.

Using a string port is probably faster when concatenating very many or very long strings. Otherwise there's unlikely to be much speed difference.

Without delimiter argument

Using fold

(define (string-join strings)
  (fold-right string-append "" strings))

Using recursion

(define (string-join strings)
  (let loop ((strings strings) (so-far ""))
    (if (null? strings)
        so-far
        (loop (cdr strings) (string-append so-far (car strings))))))

Using a string port

(define (string-join strings)
  (parameterize ((current-output-port (open-output-string)))
    (for-each write-string strings)
    (get-output-string (current-output-port))))

With a delimiter argument

Using fold

(define (string-join strings delimiter)
  (if (null? strings)
      ""
      (fold (lambda (s so-far) (string-append so-far delimiter s))
            (car strings)
            (cdr strings))))

Using recursion

(define (string-join strings delimiter)
  (if (null? strings)
      ""
      (let loop ((strings (cdr strings)) (so-far (car strings)))
        (if (null? strings)
            so-far
            (loop (cdr strings)
                  (string-append so-far delimiter (car strings)))))))

Using a string port

(define (string-join strings delimiter)
  (if (null? strings)
      ""
      (parameterize ((current-output-port (open-output-string)))
        (write-string (car strings))
        (for-each (lambda (s)
                    (write-string delimiter)
                    (write-string s))
                  (cdr strings))
        (get-output-string (current-output-port)))))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.