如何将字符串集合连接到具有前置位置的单个字符串?

时间:2015-05-07 09:27:22

标签: clojure

假设我有这个

(def base ["one" "two" "three"])

我想将其转换为:

1. one
2. two
3. three

(又名1. one \n2. two \n3. three

join,我不确定在加入之前我可以附加一个计数器:

(clojure.string/join " \n" base)
=> "one \ntwo \nthree"

doseq或类似的,加上一个原子,我确实得到了单独的字符串但后来必须连接,比如

(def base ["one" "two" "three"])

(def pos (atom 0))

(defn add-pos
  [base]
  (for [b base]
    (do 
      (swap! pos inc)
      (str @pos ". " b))))

(let [pos-base (add-pos base)]
  (clojure.string/join " \n" pos-base))

=> "1. one \n2. two \n3. three"

虽然它有效,但我不知道如果使用带有for语句的原子是他最好的方法,它看起来并不是一个非常混乱的。

请问有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

这是keep-indexed的工作:

user> (keep-indexed #(str (inc %1) ". " %2) ["one" "two" "three"])
("1. one" "2. two" "3. three")
user> (clojure.string/join "\n"
         (keep-indexed 
            #(str (inc %1) ". " %2) 
            ["one" "two" "three"]))
"1. one\n2. two\n3. three"

答案 1 :(得分:3)

schaueho的保留索引的一个小替代品是map-indexed(发现一个模式?)

(def base ["one" "two" "three"])

(defn numbered-list [s]
  (->> s
       (map-indexed #(str (inc %1) ". " %2))
       (interpose \newline)
       (apply str)))

(numbered-list base) ; => "1. one\n2. two\n3. three"

答案 2 :(得分:3)

显然是interleave的工作。

(->> (interleave (rest (range)) (repeat ". ") base (repeat " \n"))
     (apply str))

;-> "1. one \n2. two \n3. three \n"