Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 971
LocustHorde Avatar asked Apr 08 '14 16:04

LocustHorde


3 Answers

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")
like image 55
A. Webb Avatar answered Oct 23 '22 15:10

A. Webb


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")
like image 21
Kyle Avatar answered Oct 23 '22 14:10

Kyle


You can use reduce

user=> (reduce #(conj % (str (first %) %2)) '() "Ninja")
("Ninja" "Ninj" "Nin" "Ni" "N")
like image 31
Scott Avatar answered Oct 23 '22 15:10

Scott