Как повторить строку n раз идиоматическим образом? - PullRequest
34 голосов
/ 25 марта 2011

В Ruby "str" * 3 даст вам "strstrstr".В Clojure самое близкое, что я могу вспомнить, это (map (fn [n] "str") (range 3)) Есть ли более идиоматический способ сделать это?

Ответы [ 7 ]

57 голосов
/ 25 марта 2011

Как насчет этого?

(apply str (repeat 3 "str"))

Или просто

(repeat 3 "str")

, если вы хотите последовательность вместо строки.

38 голосов
/ 26 марта 2011

И еще одна забавная альтернатива с использованием протоколов:

(defprotocol Multiply (* [this n]))

Далее расширен класс String:

(extend String Multiply {:* (fn [this n] (apply str (repeat n this)))})

Так что теперь вы можете «удобно» использовать:

(* "foo" 3)
10 голосов
/ 26 марта 2011

Вы также можете использовать функцию повтора из clojure.contrib.string.Если вы добавите это в свое пространство имен с помощью require, например

(ns myns.core (:require [clojure.contrib.string :as str]))

, то

(str/repeat 3 "hello")

даст вам

"hellohellohello"
9 голосов
/ 10 августа 2012

Просто для того, чтобы добавить еще несколько удивительных и, надеюсь, заставляющих задуматься решений.

user=> (clojure.string/join (repeat 3 "str"))
"strstrstr"

user=> (format "%1$s%1$s%1$s" "str")
"strstrstr"

user=> (reduce str (take 3 (cycle ["str"])))
"strstrstr"

user=> (reduce str (repeat 3 "str"))
"strstrstr"

user=> (reduce #(.concat %1 %2) (repeat 3 "str"))
"strstrstr"
3 голосов
/ 26 марта 2011

Или используйте функцию повтора, которая поставляется с clojure-contrib ' string package . В этом случае вы можете использовать (clojure.contrib.string / repeat 3 "str"), что приводит к "strstrstr".

0 голосов
/ 14 мая 2018

Я бы не стал утверждать, что это идиоматично, но можно также повторить строку, используя функцию clojure cl-format , которая наследуется от общего lisp.Обычный шутник в свою очередь пересаживал его из Фортрана, который придумал эту работу в 50-х годах.

И вот мы в 2018 году ...

Пример:

user=> (cl-format nil "~v@{~a~:*~}" 5 "Bob")
"BobBobBobBobBob"

Строка формата работает следующим образом:

  • первыйспецификатор формата ~5@{, где пятерка извлекается из списка аргументов, поскольку перед @ стоит v.~5@{ в свою очередь означает итерацию 5 раз с использованием всего списка аргументов (строка «Bob») в качестве итерируемого.
  • внутри фигурных скобок (фигурное выражение заканчивается ~}), мы печатаем строку «Bob» с помощью ~a, а затем «перемещаем указатель аргумента» на одну позицию назад, используя конструкцию ~:*так что мы можем снова «потреблять» аргумент «Боб».

Вуаля, 5 повторений Боба.

Следует отметить, что cl-format может либо вернуть созданную строку (если второй аргумент равен nil), вывести ее в текущий *out* (если второй аргумент true), либо вывестиэто писателю (если вторым аргументом является писатель).

Для получения дополнительной информации о синтаксисе строки формата вы можете обратиться к:

Форматированный вывод в символьные потоки

в общем спискессылка на язык и, возможно, на:

Исключение формата из lisp

, почему можно утверждать, что cl-format - плохая идея.

0 голосов
/ 29 декабря 2014

неидиоматическое решение: (т.е.: НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО)

((fn [[x & xs]] (применить (eval x) xs)) (повторить 4 'стр.))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...