我有几个字符串:
(def a "some random string")
(def b "this is a text")
现在我想连接它们的一部分来创建一个字符串“some text”。不幸的是,下面的两个字符串都不起作用。
(clojure.string/join " " [(take 4 a) (take-last 4 b)])
(str (take 4 a) " " (take-last 4 b))
这是因为函数take
和take-last
返回了延迟序列。问题是:连接多个懒惰的字符串序列并返回一个字符串的正确方法是什么?
修改:我找到了一个解决方案 - (apply str (concat (take 4 a) " " (take-last 4 a)))
- 但这是最正确的方法吗?
答案 0 :(得分: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
返回“视图”在不分配新存储的情况下进入输入String
- 这是substring
包装的Java subs
方法的行为。如果您立即将"s"
移至subs
并且不保留其他任何引用,则这不是问题,因为join
会在拉出字符后将其丢弃。
如果你最终使用懒惰的字符序列,那么除了使用(map (partial apply str) [...your vector here...])
之类的东西将clojure.string/join
的输入转换成字符串之外,没有什么可以做的。
答案 1 :(得分:1)
尝试这一点,是的,因为你的代码的结果不合适,懒惰就是懒惰。
(str (apply str (take 4 a)) " " (apply str (take-last 4 b)))
答案 2 :(得分:1)
(str/join " " (map (fn [f col] (f col))
[first last]
(map #(str/split % #" ") [a b])))