LazySeq ofJava.lang.Characterのようなものがあるとしましょう
(\b \ \! \/ \b \ \% \1 \9 \/ \. \i \% \$ \i \space \^@)
これを文字列に変換するにはどうすればよいですか?私は自明のことを試しました
(String. my-char-seq)
しかしそれは投げます
Java.lang.IllegalArgumentException: No matching ctor found for class Java.lang.String (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]
文字列コンストラクターはLazySeqではなくプリミティブchar []を期待しているためだと思います。それで私は何かを試しました
(String. (into-array my-char-seq))
ただし、同じ例外がスローされます。今問題はinto-arrayがプリミティブchar []ではなくJava.lang.Character []を返すことです。私は実際にこのように自分のキャラクターシーケンスを生成するので、これはイライラします
(map #(char (Integer. %)) seq-of-ascii-ints)
基本的に私はASCII文字; 65 = Aなど)を表すintのシーケンスを持っています。プリミティブ型強制関数(char x)を明示的に使用していることがわかります。
つまり、私のmap関数はプリミティブcharを返しますが、Clojure map関数は全体的にJava.lang.Characterオブジェクト。
これは機能します:
(apply str my-char-seq)
基本的に、strは、その各引数に対してtoString()を呼び出してから、それらを連結します。ここではapplyを使用して、シーケンス内の文字を引数としてstrに渡します。
別の方法は、次のようにclojure.string/join
を使用することです。
(require '[clojure.string :as str] )
(assert (= (vec "abcd") [\a \b \c \d] ))
(assert (= (str/join (vec "abcd")) "abcd" ))
(assert (= (apply str (vec "abcd")) "abcd" ))
セパレータを受け入れるclojure.string/join
の代替形式があります。見る:
http://clojuredocs.org/clojure_core/clojure.string/join
より複雑な問題については、strcat
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 string"
特殊なケースとして、問題のシーケンスの基になるタイプがclojure.lang.StringSeq
次のこともできます:
(.s (my-seq))
これは、clojureのStringSeqクラスからpublic final CharSequenceフィールドを取り出すだけなので、非常にパフォーマンスが高くなります。
例:
(type (seq "foo"))
=> clojure.lang.StringSeq
(.s (seq "foo"))
=> "foo"
(type (.s (seq "foo")))
=> Java.lang.String
タイミングの影響の例(および型ヒントを使用する場合の違いに注意してください):
(time
(let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
(dotimes [_ 1000000]
(apply str q))))
"Elapsed time: 620.943971 msecs"
=> nil
(time
(let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
(dotimes [_ 1000000]
(.s q))))
"Elapsed time: 1232.119319 msecs"
=> nil
(time
(let [^StringSeq q (seq "xxxxxxxxxxxxxxxxxxxx")]
(dotimes [_ 1000000]
(.s q))))
"Elapsed time: 3.339613 msecs"
=> nil