assoc - Cómo repetir la cadena n veces en forma idiomática clojure?
clojure concat (7)
¿Qué tal esto?
(apply str (repeat 3 "str"))
O solo
(repeat 3 "str")
si quieres una secuencia en lugar de una cadena.
En Ruby, "str" * 3
te dará "strstrstr". En Clojure, lo más cercano que puedo pensar es (map (fn [n] "str") (range 3))
¿Hay una forma más idiomática de hacerlo?
O use la función de repetición que viene con el paquete de cadenas clojure-contrib ''. En ese caso, puede usar (clojure.contrib.string / repeat 3 "str") que da como resultado "strstrstr".
Solo para arrojar algunas soluciones más increíbles y, con suerte, que inviten a la reflexión.
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"
También podría usar la función de repetición de clojure.contrib.string. Si agrega esto a su espacio de nombres usando require como
(ns myns.core (:require [clojure.contrib.string :as str]))
entonces
(str/repeat 3 "hello")
Te regalaré
"hellohellohello"
Y una alternativa más divertida usando protocolos:
(defprotocol Multiply (* [this n]))
Luego, la clase String se extiende:
(extend String Multiply {:* (fn [this n] (apply str (repeat n this)))})
Entonces ahora puede usar ''convenientemente'':
(* "foo" 3)
Yo no diría que esto es idiomático, pero también es posible repetir una cadena usando la función clojure cl-format que clojure hereda del ceceo común. El ceceo común a su vez lo trasplantó de FORTRAN, que surgió con este trabajo en los años 50.
Y aquí estamos en 2018 ...
Ejemplo:
user=> (cl-format nil "~v@{~a~:*~}" 5 "Bob")
"BobBobBobBobBob"
La cadena de formato funciona de la siguiente manera:
- el primer especificador de formato es
~5@{
donde los cinco se extraen de la lista de argumentos ya que hay unav
delante del@
. el~5@{
a su vez significa iterar 5 veces usando toda la lista de argumentos (la cadena "Bob") como iterable. - dentro de los curlies (la expresión rizada termina con
~}
), imprimimos la cadena "Bob" con~a
y luego "movemos el puntero del argumento" hacia atrás una posición utilizando el constructo~:*
para que podamos "consumir" el argumento "Bob" de nuevo.
Voila, 5 repeticiones de Bob.
Debe tenerse en cuenta que cl-format
puede devolver la cadena producida (si el segundo argumento es nulo), imprimirlo al actual *out*
(si el segundo argumento es true
), o imprimirlo a un escritor (si es el segundo argumento es un escritor).
Para los detalles demasiado sangrientos sobre la sintaxis de la cadena de formato, puede consultar:
Salida formateada a secuencias de caracteres
en el lisp común, la referencia del idioma y, posiblemente, a:
por qué podría argumentarse que cl-format
es una mala idea.
solución unidiomática: (es decir: NO HACER ESTO SIEMPRE)
((fn [[x & xs]] (aplicar (eval x) xs)) (repetir 4 ''str))