assoc clojure

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 una v 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:

Eliminando el formato de lisp

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