## Removing Spaces

### February 11, 2020

We have a simple task today, with dozens of potential solutions:

Write a program to remove all spaces from a string.

Your task is to write a program to remove all spaces from a string. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 12 Responses to “Removing Spaces”

1. Pascal Bourguignon said

(defun remove-all-spaces (string) (remove #\space string))

(remove-all-spaces “Hello World !”) ; –> “HelloWorld!”

2. Zack said

Nice drill! Although there are more interesting ways of solving this, I’d go with the simplest one, using Julia:
RemoveSpaces(x::String) = join(split(x, ” “))

Fortunately, it doesn’t need any packages either.

3. d1rge said

sed ‘s/ //g’

Am I cheating?

4. Steve said

Klong version

```
word::"  Programming  Praxis  "
"  Programming  Praxis  "

{" "=\$x}'word :"Flag if position = space"
[1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1]

{~" "=\$x}'word  :"Flag is position not space"
[0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0]

&{~" "=\$x}'word  :"Only include position number of no spaces"
[2 3 4 5 6 7 8 9 10 11 12 15 16 17 18 19 20]

word@&{~" "=\$x}'word  :"Get value for each of those positions"
"ProgrammingPraxis"
```
5. Daniel said

Here’s a solution in Python.

```def remove_char(s, char=' '):
return s.replace(char, '')

print(remove_char('p r o g r a m m i n g _ p r a x i s'))
print(remove_char('programming praxis', 'p'))
```

Output:

```programming_praxis
rogramming raxis
```
6. matthew said

```Prelude Control.Monad> f = (>>= ap (flip replicate) (fromEnum . (' ' /=)))
Prelude Control.Monad> f "the quick brown fox"
"thequickbrownfox"
```
7. Daniel said

Here’s a solution in C.

```#include <stdio.h>
#include <stdlib.h>

void remove_char(char* s, char c) {
char* p1 = s;
char* p2 = s;
while (1) {
*p1 = *p2;
if (*p2 == '\0') break;
if (*p1 != c) ++p1;
++p2;
}
}

int main(int argc, char* argv[]) {
if (argc != 3) return EXIT_FAILURE;
remove_char(argv, *argv);
printf("%s\n", argv);
return EXIT_SUCCESS;
}
```

Example usage:

```\$ ./a.out ' ' 'p r o g r a m m i n g _ p r a x i s'
programming_praxis

\$ ./a.out 'p' 'programming praxis'
rogramming raxis
```
8. matthew said

```Prelude Control.Monad> f = (>>= \a -> case a of ' ' -> mzero; _ -> return a)
Prelude Control.Monad> f "the quick brown fox"
"thequickbrownfox"
```
9. matthew said

Or even:

```> import Control.Conditional
> import Control.Applicative
> f = (>>= liftA3 if' (==' ') (const mzero) return)
> f "the quick brown fox"
"thequickbrownfox"
```
10. matthew said

Last one – there is an ‘ifM’ function in Control.Conditional that lifts if’ (the conditional function) into a monad (in this case, the function monad, so ‘ifM f g h’ is ‘if f x then g x else h x’ and I don’t need Control.Applicative any more. The bind, mzero and return are in the list monad (so are concatMap, empty list, and \x->[x] respectively):

```Prelude Control.Conditional Control.Monad> f = (>>= ifM (==' ') (const mzero) return)
Prelude Control.Conditional Control.Monad> f "the quick brown fox"
"thequickbrownfox"
```
11. Steve said

@matthew: Can you explain your Haskell programs? Amazing what 1 line can do! Thanks, Steve

12. matthew said

@Steve: Here’s an attempt at an explanation (I might post this elsewhere, so grateful for any comments):

In Haskell, a string is just a list of characters, so one way of doing this is to map a function over that list. What should that function be? It can’t just be a map from Char to Char – what would it do for the space character? A possibility, since we are already dealing with lists is to use a function Char->[Char], ie. take a Char and return a list of Chars:

```f s = concat (map g s) where
g ' ' = []
g c = [c]

f "the quick brown fox"
"thequickbrownfox"
```

Now let’s start the fooling around.

First of all, let’s go point free. f is just applying two functions (concat and map g) to its argument, so we can rewrite as a composition:

```f = concat . map g where
g ' ' = []
g c = [c]
```

Now, it would be good to get rid of that auxiliary function, one way would be to use a lambda:

```f = concat . map (\c -> case c of ' ' -> []; _ -> [c])
```

or:

```f = concat . map (\c -> if c == ' ' then [] else [c])
```

Alternatively, we can use an ‘Iverson bracket’ and use the numeric value of the boolean test as a parameter to ‘replicate’, ‘replicate n a’ makes n copies of a, and ‘fromEnum False’ is 0, ‘fromEnum True’ is 1:

```f = concat . map (\c -> replicate (fromEnum (' ' /= c)) c)
```

and we should recognize that ‘concat . map f’ is just a monadic bind: (>>= f):

```f = (>>= (\c -> replicate (fromEnum (' ' /= c)) c))
```

Now that lambda is of the form: \c -> (f (g c) c) which is almost the form of the S-combinator:

```s f g x = (f x)(g x)
```

and if we change the parameter order of replicate we get exactly this form:

```f = (>>= s (flip replicate) (fromEnum . (' ' /=)))
```

Haskell doesn’t have an S combinator as such, but the Applicative operator ‘ap’ is equivalent to S in the function monad, so finally we end up with:

```f = (>>= ap (flip replicate) (fromEnum . (' ' /=)))
```

That’s nice, but the use of replicate is a bit obscure, let’s go back to the case form:

```f = (>>= \c -> case c of ' ' -> []; _ -> [c])
```

or

```f = (>>= \c -> if c == ' ' then [] else [c])
```

Being Haskell programmers we can’t help noticing that [] and [c] are both monadic – [] is just ‘monadic zero’ in the list monad, and in the same monad, [c] is ‘return c’, so now we have:

```f = (>>= \c -> case c of ' ' -> mzero; _ -> return c)
f = (>>= \c -> if c == ' ' then mzero else return c)
```

Not much more to be done with the ‘case’ form, but we can make use of the laziness of Haskell to rewrite the ‘if’ form: we can write ‘if’ as a function:

```if' x y z = if x then y else z
```

and laziness ensures that only one of y and z get evaluated, so we have:

```f = (>>= \c -> if' (c == ' ') mzero (return c))
```

or:

```f = (>>= \c -> if' (c == ' ') ((const mzero) c) (return c))
```

where const is just the K-combinator:

```const x y = x
```

so what I want is a “functional if”:

```if'' f g h x = if' (f x) (g x) (h x)

f = (>>= if'' (== ' ') (const mzero) return)
```

and this can be done by “lifting” if’ into the function Monad (though actually, this is an Applicative operation):

```import Control.Applicative
f = (>>= liftA3 if' (==' ') (const mzero) return)
```

or, even better, use the ifM function directly (defined in Control.Conditional):

```> import Control.Conditional
> :t ifM
ifM :: (ToBool bool, Monad m) => m bool -> m a -> m a -> m a
```
```f = (>>= ifM (==' ') (const mzero) return)
```

For a final monadic flourish, we can observe that ‘const’ itself is just ‘return’ in the function monad and we get:

```f = (>>= ifM (==' ') (return mzero) return)
```

Now f works for other instances of Monad (or rather MonadPlus, since we require mzero), for example Maybe and IO:

```> map f [Nothing,Just ' ',Just 'a']
[Nothing,Nothing,Just 'a']

> f getChar
<types space>
^J*** Exception: user error (mzero)
> f getChar
<types 'a'>
a'a'
```