2

私はいくつかの文字列を持っています:

(def a "some random string")
(def b "this is a text")

次に、それらの一部を連結して、文字列「テキスト」を作成します。残念ながら、以下の両方の文字列は機能しませんでした。

(clojure.string/join " " [(take 4 a) (take-last 4 b)])
(str (take 4 a) " " (take-last 4 b))

これは、関数がレイジーシーケンスtaketake-last返すためです。問題は、文字列の複数の遅延シーケンスを連結して1つの文字列を返す適切な方法は何ですか?

編集:私は1つの解決策を見つけました---(apply str (concat (take 4 a) " " (take-last 4 a)))しかしそれは最も正しい方法ですか?

4

3 に答える 3

6

シーケンス関数を使用して入力文字列をスライスするのではなく、はるかに効率的な関数を使用することをお勧めしますsubs(部分文字列の場合。GC 関連の警告があることに注意してください。以下を参照してください)。

(subs "asdf" 1 2)
; => "s"

;; a and b as in the question text
(clojure.string/join " " [(subs a 0 4) (subs b (- (count b) 4))])
; => "some text"

前述の注意点は、"s"ここの最初の例で返されたものがガベージ コレクションの対象外である限り、オリジナルもそうであるということです"asdf"(新しいストレージを割り当てずsubsに入力に「ビュー」を返すため、これはラップする Java のメソッドの動作です)。 )。文字をプルした後に破棄されるため、すぐに に渡し、他の参照を保持しない場合、これは問題ではありません。Stringsubstringsubs"s"subsjoin

結局のところ、怠惰な文字列で作業することになった場合は(map (partial apply str) [...your vector here...])、入力をclojure.string/join文字列に変換するようなものを使用する以外に何もすることはありません。

于 2012-08-22T09:54:36.200 に答える
1
(str/join " " (map (fn [f col] (f col))
               [first last]
               (map #(str/split % #" ") [a b])))
于 2012-08-23T05:52:39.190 に答える
1

これを試してみてください。はい、怠惰のためにコードの結果が適切ではありません。

(str (apply str (take 4 a)) " " (apply str (take-last 4 b)))
于 2012-08-22T09:56:38.660 に答える