[erlang-questions] Smart way to trim a binary?

Andreas Hillqvist <>
Tue Jun 30 17:32:57 CEST 2009


Hi List.

What would be the most efficient way to write it for the compiler to optimize?

trim(Bin) when is_binary(Bin) ->
    right_trim_binary(left_trim_binary(Bin));
trim(List) when is_list(List) ->
    right_trim_list(left_trim_list(List)).

left_trim_binary(<<$\s, Bin/binary>>) ->
    left_trim_binary(Bin);
left_trim_binary(<<$\s, Bin/binary>>) ->
    left_trim_binary(Bin);
left_trim_binary(<<$\t, Bin/binary>>) ->
    left_trim_binary(Bin);
left_trim_binary(<<$\n, Bin/binary>>) ->
    left_trim_binary(Bin);
left_trim_binary(<<$\r, Bin/binary>>) ->
    left_trim_binary(Bin);
left_trim_binary(Bin) ->
    Bin.

%%Will this compile? Unsure, but why not? ;-)
right_trim_binary(<<Bin/binary, $\s>>) ->
    right_trim_binary(Bin);
right_trim_binary(<<Bin/binary, $\s>>) ->
    right_trim_binary(Bin);
right_trim_binary(<<Bin/binary, $\t>>) ->
    right_trim_binary(Bin);
right_trim_binary(<<Bin/binary, $\n>>) ->
    right_trim_binary(Bin);
right_trim_binary(<<Bin/binary, $\r>>) ->
    right_trim_binary(Bin);
right_trim_binary(Bin) ->
    Bin.



left_trim_list([$\s | List]) ->
    left_trim_list(List);
left_trim_list([$\s | List]) ->
    left_trim_list(List);
left_trim_list([$\t | List]) ->
    left_trim_list(List);
left_trim_list([$\n | List]) ->
    left_trim_list(List);
left_trim_list([$\r | List]) ->
    left_trim_list(List);
left_trim_list(List) ->
    List.

right_trim_list(List) ->
    lists:reverse(left_trim_list(lists:reverse(List))).

As far as I understand it trim_binary/1 will return a subbinary, no
copy will be performed?


This could also be writen as, with some improved readability (yes,
with an ugly Macro. Pleas may god forgive me):

-define(IS_WHITESPACE(Char), Char =:= $\s, Char =:= $\t, Char =:= $\n,
Char =:= $\r).

trim(Bin) when is_binary(Bin) ->
    right_trim_binary(left_trim_binary(Bin));
trim(List) when is_list(List) ->
    right_trim_list(left_trim_list(List)).

left_trim_binary(<<Char, Bin/binary>>) when ?IS_WHITESPACE(Char) ->
    left_trim_binary(Bin);
left_trim_binary(Bin) ->
    Bin.

right_trim_binary(<<Bin/binary, Char>>) when ?IS_WHITESPACE(Char) ->
    right_trim_binary(Bin);
right_trim_binary(Bin) ->
    Bin.



left_trim_list([Char | List]) when ?IS_WHITESPACE(Char) ->
    left_trim_list(List);
left_trim_list(List) ->
    List.

right_trim_list(List) ->
    lists:reverse(left_trim_list(lists:reverse(List))).


So this could be considred as a vote for allowing side-effect free
functions as guards?. ;-)
I know the dicussion has been up before on the list.



Kind regards
Andreas Hillqvist


2009/6/24 Steve Davis <>:
> I have this feeling that there's a much smarter way to trim a string
> presented as a binary rather than this (mostly found in couch_util)...
>
> trim(Bin) when is_binary(Bin) ->
>        list_to_binary(trim(binary_to_list(Bin)));
> trim(String) when is_list(String) ->
>    String2 = lists:dropwhile(fun is_whitespace/1, String),
>    lists:reverse(lists:dropwhile(fun is_whitespace/1, lists:reverse
> (String2))).
>
> is_whitespace($\s)-> true;
> is_whitespace($\t)-> true;
> is_whitespace($\n)-> true;
> is_whitespace($\r)-> true;
> is_whitespace(_Else) -> false.
>
> ...anybody have a nice way of doing this?
>
> TIA & BR,
> /sd
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


More information about the erlang-questions mailing list