1

As we know, (map f [a b c]) is equivalent to [(f a) (f b) (f c)].

My question is: The evaluation result of (map #(- (int %) (int \0)) "1234") is (1 2 3 4), why does it return the results of applying #(- (int %) (int \0)) to every digits of "1234", rather than the string "1234" as a whole? How should I understand this code example?

5
  • This has bitten me quite often Commented Aug 4, 2014 at 18:52
  • One qualification: The result of (map f [a b c]) isn't exactly the same as the result of [(f a) (f b) (f c)], since map returns a lazy sequence rather than a vector. I think it's correct to say that the result of (map f [a b c]) is the same as the result of (lazy-seq [(f a) (f b) (f c)]), and that result of (vec (map f [a b c])) is the same as the result of [(f a) (f b) (f c)]. (If I'm wrong about some details, more knowledgeable people will hopefully correct me.) Commented Aug 5, 2014 at 4:32
  • You don't need map if you just want to call a function using a single argument. If that's what you want, then don't use map: (#(- (int %) (int \0)) "1234") Commented Aug 5, 2014 at 15:01
  • @DaoWen Your code produces ClassCastException java.lang.String cannot be cast to java.lang.Character ... - surely not what's intended. Commented Aug 5, 2014 at 18:59
  • @Thumbnail - Ha, you're right, thanks. You would need to use Integer/parseInt to convert the string to an int instead of the int "cast" that works for chars. The point is that I don't really understand the OP's question—*if you just want to apply the function to the string (not the individual characters), why don't you just call it directly rather than using map?* Apparently I'm missing something... Commented Aug 5, 2014 at 20:23

2 Answers 2

4

map calls seq on all arguments after the first. seq turns a string into a sequence of characters.

Sign up to request clarification or add additional context in comments.

Comments

1

Clojure can treat a string as a sequence - of characters. This is useful because you can:

  • map things over the string
  • partition the string
  • get locations by index
  • do everything else sequences do.

It's perhaps a bit annoying having to remember to put the resulting sequence back into a string by wrapping the sequence manipulating expression in a call to str.

2 Comments

it may make sense to merge our answers into yours, since yours is more complete anyway - perhaps making it clear that it is specifically map which calls seq on args, and showing (apply str (map f string)) as the canonical way to get a string back out the other side.
I value the simplicity, elegance, and implicit generality of your answer, @noisesmith, as well as Arthur Ulfeldt's discussion of the ramifications and purpose of map's behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.