【问题标题】:Join multiple lazy sequences of strings in Clojure在 Clojure 中加入多个惰性字符串序列
【发布时间】:2012-08-22 09:39:15
【问题描述】:

我有几个字符串:

(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 返回惰性序列。问题是:连接多个惰性字符串序列并返回一个字符串的正确方法是什么?

编辑:我找到了一种解决方案 - (apply str (concat (take 4 a) " " (take-last 4 a))) - 但这是最​​正确的方法吗?

【问题讨论】:

  • 您的编辑方式对我来说看起来不错。

标签: string clojure concatenation lazy-sequences


【解决方案1】:

而不是使用序列函数对输入字符串进行切片,您可能希望使用 much 更有效的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 上返回一个“视图”无需分配新的存储空间——这是 Java 的 substring 方法的行为,其中 subs 包装)。如果您立即将"s" 交给subs 并且不保留对它的其他引用,这不是问题,因为join 会在提取字符后丢弃它。

如果你最终还是使用了惰性字符序列,那么除了使用(map (partial apply str) [...your vector here...]) 之类的东西将clojure.string/join 的输入转换为字符串之外,别无他法。

【讨论】:

    【解决方案2】:

    试试这个,是的,因为你的代码的结果不正确。

    (str (apply str (take 4 a)) " " (apply str (take-last 4 b)))
    

    【讨论】:

    • 问题不在于懒惰。但是对 LazySeq 字符调用 toString 不会返回由该序列中的字符组成的字符串。 OP 对于字符向量或字符列表也会有类似的问题。
    【解决方案3】:
    (str/join " " (map (fn [f col] (f col))
                   [first last]
                   (map #(str/split % #" ") [a b])))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2010-12-08
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      相关资源
      最近更新 更多