Comment puis-je convertir un LazySeq de caractères en une chaîne dans Clojure?

Disons que j’ai un LazySeq de java.lang.Character comme

(\b \ \! \/ \b \ \% \1 \9 \/ \. \i \% \$ \i \space \^@) 

Comment puis-je convertir cela en chaîne? J’ai essayé l’évidence

 (Ssortingng. my-char-seq) 

mais ça jette

 java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Ssortingng (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Comstackr$ComstackrException] 

Je pense que parce que le constructeur Ssortingng attend un caractère primitif [] au lieu d’un LazySeq . Alors j’ai essayé quelque chose comme

 (Ssortingng. (into-array my-char-seq)) 

mais il jette la même exception. Le problème maintenant est que into-array renvoie un java.lang.Character [] au lieu d’un caractère primitif [] . C’est frustrant, parce que je génère ma séquence de caractères comme ça

 (map #(char (Integer. %)) seq-of-ascii-ints) 

Fondamentalement, j’ai une séquence d’ints représentant des caractères ASCII; 65 = A, etc. Vous pouvez voir que j’utilise explicitement la fonction de coercition de type primitif (char x) .

Cela signifie que ma fonction de carte renvoie un caractère primitif, mais que la fonction de carte Clojure retourne globalement l’object java.lang.Character .

Cela marche:

 (apply str my-char-seq) 

Fondamentalement, str appelle toSsortingng () sur chacun de ses arguments, puis les concatène. Ici, nous utilisons apply pour passer les caractères de la séquence en arguments à str .

Une autre méthode consiste à utiliser clojure.ssortingng/join , comme suit:

 (require '[clojure.ssortingng :as str] ) (assert (= (vec "abcd") [\a \b \c \d] )) (assert (= (str/join (vec "abcd")) "abcd" )) (assert (= (apply str (vec "abcd")) "abcd" )) 

Il existe une autre forme de clojure.ssortingng/join qui accepte un séparateur. Voir:

http://clojuredocs.org/clojure_core/clojure.ssortingng/join

Pour des problèmes plus compliqués, vous pouvez également strcat dans la bibliothèque Tupelo :

 (require '[tupelo.core :as t] ) (prn (t/strcat "I " [ \h \a nil \v [\e \space (byte-array [97]) [ nil 32 "complicated" (Math/pow 2 5) '( "str" nil "ing") ]]] )) ;=> "I have a complicated ssortingng" 

Comme cas particulier, si le type sous-jacent de la séquence en question est clojure.lang.SsortingngSeq vous pouvez également faire:

 (.s (my-seq)) 

ce qui est extrêmement performant car il ne fait que sortir le champ public final CharSequence de la classe clojure SsortingngSeq.

Exemple:

 (type (seq "foo")) => clojure.lang.SsortingngSeq (.s (seq "foo")) => "foo" (type (.s (seq "foo"))) => java.lang.Ssortingng 

un exemple des implications du timing (et notez la différence lorsque vous utilisez un indice de type):

 (time (let [q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (apply str q)))) "Elapsed time: 620.943971 msecs" => nil (time (let [q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (.sq)))) "Elapsed time: 1232.119319 msecs" => nil (time (let [^SsortingngSeq q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (.sq)))) "Elapsed time: 3.339613 msecs" => nil