4

I'm working on 4clojure problem 29 : "Get the Caps"

(= (__ "HeLlO, WoRlD!") "HLOWRD")

I've written a solution in the REPL:

user=> (apply str (filter (fn [foo] (some #(= % foo) 
         (map char (range 65 91)))) "AbC"))
"AC"

But as you can see my parameter "AbC" is nested two parentheses in. How would I move my parameter to the outside so I can use it in the 4clojure test? Have I approached the problem in the wrong way?

0

3 Answers 3

5

You don't need to move the a parameter to the outside, you can just use the same technique you used to create the filtering function, that is, with fn:

(fn [string] 
  (apply str 
    (filter 
      (fn [foo] (some #(= % foo) (map char (range 65 91)))) 
      string)))

As an example of this, the following two statements are the same:

(+ 1 2 3)
((fn [n] (+ 1 2 n)) 3)

However, to actually answer your question, you could use comp ("compose") and partial to move the parameter to allow eta conversion (that is the technical name for the last part of the manipulation you are attempting to do):

(comp (partial apply str)
      (partial filter (fn [foo] (some #(= % foo) 
                                       (map char (range 65 91))))))

This expression is now a function that takes a string, filters the capital letters and then converts it back to a string (notices that comp applies functions from right to left).

(NB, that last expression probably isn't very idiomatic Clojure; the first method, or one of the suggestions of others, is better.)

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

3 Comments

Thanks Huon. I needed to use the comp approach to get my solution into 4clojure's "quiz" system. Other solutions used an apply str on a regex (re-seq), but that's ok - it's reinforced two concepts - comp & re-seq.
@SoniaHamilton, it's very impolite to use someone's real name if they are posting under a pseudonym (even if their real name is associated with that pseudonym!). But good to hear :)
Also, @SoniaHamilton, you can use the anonymous function syntax with fn on 4clojure.com: (fn [x] (* 2 x)) is a working solution for problem 15.
3

You should pass a function as a solution. Something like:

(fn [text] 
    (apply str (filter (fn [foo] (some #(= % foo) 
                                        (map char (range 65 91)))) 
                       text)))

Also you can use Character.isUpperCase to filter all upper case chars: (filter (fn [ch] (Character/isUpperCase ch) text)

2 Comments

Thanks Nikita. dbaupp's solution was more helpful - in the 4clojure "quiz" the text is outside any brackets, so making it into a fn doesn't work...
@SoniaHamilton It does work. I solved the same task with fn: (fn [text] (apply str (filter #(Character/isUpperCase %) text)))
2

I'm not familiar with 4Clojure, but if it's allowed, you could use clojure.string/replace.

The following should do the trick:

(fn [s] (clojure.string/replace s #"[^A-Z]" ""))

Everything that isn't in the range A to Z is replaced with the empty string.

Comments

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.