LocustHorde
LocustHorde

Reputation: 6399

Generating substrings in clojure

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

Answers (3)

A. Webb
A. Webb

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

Scott
Scott

Reputation: 1688

You can use reduce

user=> (reduce #(conj % (str (first %) %2)) '() "Ninja")
("Ninja" "Ninj" "Nin" "Ni" "N")

Upvotes: 1

Kyle
Kyle

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

Related Questions