Reputation: 6399
I am trying to generate all the possible prefix substrings of a given string in clojure. For example, if the word is Ninja
, I want the output to be ("N" "Ni" "Nin" "Ninj" "Ninja")
I can easily do that with this:
user=> (def a "Ninja")
user => (for [x (range 1 (+ 1 (.length a)))]
(subs a 0 x))
("N" "Ni" "Nin" "Ninj" "Ninja")
And this is all fine... except.. I am using a for loop in there.. and it doesn't look very clojure-y.. is there a better / proper way to do this without the for loop or is the for loop completely okay in this case?
thank you
Upvotes: 5
Views: 646
Reputation: 26446
Mapping subs
over the length as in your for
comprehension or with map explicitly is what I'd do as well.
However, if you really want a higher level function, you could use reductions
(rest (reductions str (str) "Ninja"))
;=> ("N" "Ni" "Nin" "Ninj" "Ninja")
If you had wanted suffixes instead, you could do so nicely with iterate
and subs
since you wouldn't have to specify the end.
(take-while seq (iterate #(subs % 1) "Ninja"))
;=> ("Ninja" "inja" "nja" "ja" "a")
Upvotes: 5
Reputation: 1688
You can use reduce
user=> (reduce #(conj % (str (first %) %2)) '() "Ninja")
("Ninja" "Ninj" "Nin" "Ni" "N")
Upvotes: 1
Reputation: 22258
for
comprehensions are perfectly fine, IMO. If you'd like to see another approach, here is what I would do:
(map (partial subs a 0) (range 1 (-> a count inc)))
;; ("N" "Ni" "Nin" "Ninj" "Ninja")
Upvotes: 4