Exercise 2-4
January 20, 2017
Scheme makes is possible to write both versions of squeeze
in a single function:
(define (squeeze str c-or-s) (let ((dels (if (char? c-or-s) (list c-or-s) (string->list c-or-s)))) (list->string (filter (lambda (c) (not (member c dels))) (string->list str)))))
The second argument may be either a character or a string; the let
builds a list of characters to be deleted. Then the target string is converted to a list of characters, each is filtered according to the list of characters to be deleted, and the remaining characters are converted back to a string. The for
is typical of C, the higher-order function filter
is typical of Scheme. I’m biased, but I think the Scheme version is simpler because it doesn’t require the auxiliary variables i
and j
, which can both be a source of error. Here’s the function in action, both ways:
> (squeeze "Programming Praxis" #\P) "rogramming raxis" > (squeeze "Programming Praxis" "aeiou") "Prgrmmng Prxs"
You can run the program at http://ideone.com/pCg02E.
As a perl user I would do this a perl way…
Perl golf would get it down to
Here’s some C++:
Or some more traditional C:
Guile:
(define (squeeze str chars) (string-delete (string->char-set chars) str))
Python strings have translation-table methods.
Here’s a Haskell version. It also works on any list whose elements support equality testing.
@Globules: I was going to suggest
but really that is just your solution with mfilter instead of filter.
@matthew Your MonadPlus suggestion made me wonder what was the “most general” type I could give it. But then I got lost in a maze of twisty little typeclasses (Foldable, Alternative, etc.) and now I will just go to bed… :-)