32

I'm looking to create a list of characters using a string as my source. I did a bit of googling and came up with nothing so then I wrote a function that did what I wanted:

(defn list-from-string [char-string]
  (loop [source char-string result ()]
    (def result-char (string/take 1 source))
    (cond
     (empty? source) result
     :else (recur (string/drop 1 source) (conj result result-char)))))

But looking at this makes me feel like I must be missing a trick.

  1. Is there a core or contrib function that does this for me? Surely I'm just being dumb right?
  2. If not is there a way to improve this code?
  3. Would the same thing work for numbers too?
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
robertpostill
  • 3,820
  • 3
  • 29
  • 38

4 Answers4

53

You can just use seq function to do this:

user=> (seq "aaa")
(\a \a \a)

for numbers you can use "dumb" solution, something like:

user=> (map (fn [^Character c] (Character/digit c 10)) (str 12345))
(1 2 3 4 5)

P.S. strings in clojure are 'seq'able, so you can use them as source for any sequence processing functions - map, for, ...

TacticalCoder
  • 6,275
  • 3
  • 31
  • 39
Alex Ott
  • 80,552
  • 8
  • 87
  • 132
  • Hi! What is the meaning of [^Character c]? is ^Character to use Character/digit inside? – Polak Jan 27 '16 at 22:38
  • 3
    this is type hint, without it the clojure will use reflection to determine the argument type. This makes the function slightly faster... – Alex Ott Jan 28 '16 at 18:57
23

if you know the input will be letters, just use

user=> (seq "abc")
(\a \b \c)

for numbers, try this

user=> (map #(Character/getNumericValue %) "123")
(1 2 3)
Matthew Boston
  • 1,320
  • 10
  • 24
6

Edit: Oops, thought you wanted a list of different characters. For that, use the core function "frequencies".

clojure.core/frequencies
([coll])
  Returns a map from distinct items in coll to the number of times they appear.

Example:

user=> (frequencies "lazybrownfox")
{\a 1, \b 1, \f 1, \l 1, \n 1, \o 2, \r 1, \w 1, \x 1, \y 1, \z 1}

Then all you have to do is get the keys and turn them into a string (or not).

user=> (apply str (keys (frequencies "lazybrownfox")))
"abflnorwxyz"
Markc
  • 1,039
  • 7
  • 11
0
(apply str (set "lazybrownfox")) => "abflnorwxyz"
murtaza52
  • 46,887
  • 28
  • 84
  • 120