Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stripping Vowels in clojure

Tags:

clojure

I'm trying to write a function to strip all ASCII vowels in Clojure. I am new to Clojure, and I'm having a little trouble with strings. For example the string "hello world" would return "hll wrld". I appreciate the help!

like image 385
Joe Crawley Avatar asked Nov 28 '22 16:11

Joe Crawley


2 Answers

You can take advantage of the underlying functions on the string class for that.

user=> (.replaceAll "hello world" "[aeiou]" "")           
"hll wrld"

If that feels like cheating, you could turn the string into a seq, and then filter it with the complement of a set, and then turn that back into a string.

user=> (apply str (filter (complement #{\a \e \i \o \u}) (seq "hello world")))
"hll wrld"

Sets in clojure are also functions. complement takes a function and returns a function that returns the logical not of the original function. It's equivalent to this. apply takes a function and a bunch of arguments and calls that function with those arguments (roughly speaking).

user=> (apply str (filter #(not (#{\a \e \i \o \u} %)) (seq "hello world")))
"hll wrld"

edit

One more...

user=> (apply str (re-seq #"[^aeiou]" "hello world"))
"hll wrld"

#"[^aeiou]" is a regex, and re-seq turns the matches into a seq. It's clojure-like and seems to perform well. I might try this one before dropping down to Java. The ones that seq strings are quite a bit slower.

Important Edit

There's one more way, and that is to use clojure.string/replace. This may be the best way given that it should work in either Clojure or Clojurescript.

e.g.

dev:cljs.user=> (require '[clojure.string :as str])
nil

dev:cljs.user=> (str/replace "hello world" #"[aeiou]" "")
"hll wrld"
like image 138
Bill Avatar answered Dec 05 '22 08:12

Bill


Bill is mostly right, but wrong enough to warrant this answer I think.

user=> (.replaceAll "hello world" "[aeiou]" "")           
"hll wrld"

This solution is perfectly acceptable. In fact, it's the best solution proposed. There is nothing wrong with dropping down to Java if the solution is the cleanest and fastest.

Another solution is, like he said, using sequence functions. However, his code is a little strange. Never use filter with (not ..) or complement. There is a function specifically for that, remove:

user> (apply str (remove #{\a \e \i \o \u} "hello world"))
"hll wrld"

You also don't have to call seq on the string. All of Clojure's seq functions will handle that for you.

His last solution is interesting, but I'd prefer the first one simply because it doesn't involve (apply str ..).

like image 20
Rayne Avatar answered Dec 05 '22 10:12

Rayne