Reputation: 6399
Assume I have this
(def base ["one" "two" "three"])
I want to convert it to:
1. one
2. two
3. three
(aka 1. one \n2. two \n3. three
)
with join
, I am not sure I can append a counter before joining:
(clojure.string/join " \n" base)
=> "one \ntwo \nthree"
and with doseq
or similar, plus an atom, I do get individual strings but then will have to concatenate later on, something like
(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"
While it works, I don't know if using an atom with a for
statement is he best way to do this, it doesn't look very clojure-esque.
Is there a better way to do this please?
Upvotes: 0
Views: 179
Reputation: 9266
Clearly a job for interleave.
(->> (interleave (rest (range)) (repeat ". ") base (repeat " \n"))
(apply str))
;-> "1. one \n2. two \n3. three \n"
Upvotes: 3
Reputation: 876
A minor alternative to schaueho's keep-indexed would be map-indexed (spotting a pattern?)
(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"
Upvotes: 3
Reputation: 3504
That's a job for 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"
Upvotes: 4