Как строить строки в Clojure - PullRequest
1 голос
/ 20 января 2020

Скажем, у меня есть список элементов, таких как [1 2 3], и я хотел преобразовать его в |1|2|3|. Или, если бы я хотел повторить последовательность "---" 3 раза в "---------".

Как мне подойти к нему, чтобы я мог собрать его в такую ​​строку. Есть ли метод, похожий на Java StringBuilder? Я не ищу конкретный ответ на этот вопрос, но только общее руководство о том, как создавать строки в Clojure, так как я очень плохо знаком с языком.

Ответы [ 3 ]

4 голосов
/ 20 января 2020

Начните с Шпаргалка Clojure . Посмотрите на раздел "Струны". Некоторые примеры:

(str/join \| [1 2 3])           => "1|2|3"

(apply str (repeat 3 "---"))    => "---------"

(str
  "|"
  (str/join \| [1 2 3])
  "|")
       => "|1|2|3|"

Существуют и другие библиотеки, которые содержат много полезных строковых функций в дополнение к clojure.string:

3 голосов
/ 20 января 2020

также есть функция cl-format в базовой библиотеке clojure, которая является портом изумительного средства format для общего lisp.

(require '[clojure.pprint :refer [cl-format]])

user> (cl-format nil "~v@{~a~:*~}" 5 "10")
;;=> "1010101010"

user> (cl-format nil "|~{~a|~}" [1 2 3])
;;=> "|1|2|3|"

эта действительно мощная Тем не менее, строка формата может быть довольно сложной для читателя в случае действительно сложных шаблонов обработки строк. Тем не менее, для случаев, о которых вы спрашиваете (объединение, повтор, итерация или условный вывод), он остается в пределах понятного.

есть несколько примеров здесь , легко переводимых из cl в clojure.

PS:

user> (cl-format nil "~r" 234598284579147)
;;=> "two hundred thirty-four trillion, five hundred ninety-eight billion, two hundred eighty-four million, five hundred seventy-nine thousand, one hundred forty-seven"

user> (cl-format nil "~@r" 1232)
;;=> "MCCXXXII"
2 голосов
/ 20 января 2020

Ответ на использование (apply str ...) обычно лучший. Но здесь есть дополнительная техника и «совет для профессионалов» о трех точках в (apply str ...).

Если содержимое строки наиболее естественно генерируется функциями print (что не так в случае с ваш конкретный c примеров!), затем вы можете захватить его с помощью with-out-str:

(with-out-str
  (doseq [i (range 1 4)]
    (print "|")
    (print i))
  (println "|"))   ;; => "|1|2|3|\n"

Обычно (apply str ...) является более идиоматическим c. Вы можете использовать весь гобелен функций последовательности (interleave, interpose, repeat, cycle, ...) и извлечь результат в виде строки с помощью (apply str ...). Но вы сталкиваетесь с проблемой, если последовательность содержит вложенные последовательности. Мы упоминаем эту проблему здесь, потому что есть два решения, которые определяют c для построения строк.

Чтобы быть понятным, вложенные последовательности "работают отлично" во всех отношениях, за исключением того, что str делает с последовательностью может быть не то, что вы хотите. Например, чтобы построить «1 ------ 2 ------ 3»:

;; not quite right:
(apply str 
       (interpose 
         (repeat 2 "---") 
         (range 1 4))) ;; => "1(\"---\" \"---\")2(\"---\" \"---\")3"

Дело в том, что repeat создал последовательность, которая interpose покорно застряла между числа в большей последовательности и str при обработке большей последовательности покорно записывают вложенные последовательности в синтаксис Clojure. Чтобы лучше контролировать, как вложенные последовательности становятся строковыми, вы можете заменить (repeat 2 "---") на (apply str (repeat 2 "---")). Но если шаблон apply str в пределах apply str встречается снова и снова, это ухудшает отношение сигнал / шум программы. Альтернативой, которая может быть чище, является функция flatten (может быть, это ее единственное использование c):

(apply str 
       (flatten 
        (interpose 
         (repeat 2 "---") 
         (range 1 4))))  ;; => "1------2------3"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...