Как превратить список строк в одну строку в схеме?

Например, у меня есть (list "a" "1" "b" "2" "c" "3").

Теперь я хочу превратить этот список в один "a1b2c3".

Как я могу это сделать?

Спасибо.


person user2444642    schedule 02.06.2013    source источник


Ответы (3)


(apply string-append (list "a" "1" "b" "2" "c" "3")) или (string-append* "" (list "a" "1" "b" "2" "c" "3")) должны работать. См.: http://docs.racket-lang.org/reference/strings.html.

Если вам нужна процедура для этого, вы можете просто написать (define (strings->string sts) (apply string-append sts))

person Wes    schedule 02.06.2013
comment
Это совершенно нормально, когда вы знаете, что будете соединять только небольшое количество строк. В более общем смысле методы на основе apply создают список аргументов из своих входных данных, поэтому они могут достичь предела длины списка аргументов языковой реализации, если им предоставляется длинный список. Предел не очень высок в некоторых языковых стандартах/реализациях; не уверен, как обстоят дела с Scheme/Racket. - person Lassi; 18.04.2019
comment
В Racket у вас нет этой проблемы, безопасно использовать технику apply даже для длинных списков. - person Óscar López; 18.04.2019

Не изобретайте велосипед! в Racket для этого существует одна процедура, которая называется string-join:

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

Цитирование документация:

(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? = ""

Добавляет строки в strs, вставляя sep между каждой парой строк в strs. before-last, before-first и after-last аналогичны входным данным add-between: они задают альтернативный разделитель между двумя последними строками, строкой префикса и строкой суффикса соответственно.

person Óscar López    schedule 02.06.2013
comment
Это также реализовано в Guile. - person musarithmia; 16.05.2017

Вот некоторые реализации с разделителем и без него (то есть строка, которая вставляется между каждой парой строк, например пробел или запятая).

Функции fold и fold-right взяты из SRFI 1.

Использование строкового порта, вероятно, быстрее при объединении очень многих или очень длинных строк. В противном случае вряд ли будет большая разница в скорости.

Без аргумента-разделителя

Использование сгиба

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

Использование рекурсии

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

Использование строкового порта

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

С аргументом-разделителем

Использование сгиба

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

Использование рекурсии

(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)))))))

Использование строкового порта

(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)))))
person Lassi    schedule 18.04.2019