[erlang-questions] Case-insensitive key search on a list
Bob Ippolito
bob@REDACTED
Mon Apr 30 20:23:38 CEST 2012
On Mon, Apr 30, 2012 at 10:54 AM, Tristan Sloughter <
tristan.sloughter@REDACTED> wrote:
> So you want to find a tuple in a list converted from JSON so the key is
> binary. And not only that, you want it to be case insensitive!
>
> Now as far as I found, I'm only now bothering to go back to this code and
> ask why, there is only string:equal/2 and it doesn't support case
> insensitive matching. And not only that but string:to_lower/1 only supports
> lists. So I ended up with a conversion to a list, then to_lower and then
> back to a binary....
>
> It is too ugly to think it was right... Does anyone know a better way of
> doing this? I feel I am missing something obvious.
>
> case_insensitive_binary_string_keyfind(_String, _Pos, []) ->
> false;
> case_insensitive_binary_string_keyfind(String, Pos, [H|T]) ->
> case list_to_binary(
> string:to_lower(
> binary_to_list(
> element(Pos, H)))) of
> String ->
> H;
> _ ->
> case_insensitive_binary_string_keyfind(String, Pos, T)
> end.
>
Well, just implement it yourself. Maybe something like this:
lower_match(<<C, B0/binary>>, <<C, B1/binary>>) ->
lower_match(B0, B1);
lower_match(<<C0, B0/binary>>, <<C1, B1/binary>>)
when (C1 >= $a andalso C1 =< $z andalso C0 >= $A andalso
(C0 + ($a - $A)) =:= C1) ->
lower_match(B0, B1);
lower_match(<<C1, B0/binary>>, <<C0, B1/binary>>)
when (C1 >= $a andalso C1 =< $z andalso C0 >= $A andalso
(C0 + ($a - $A)) =:= C1) ->
lower_match(B0, B1);
lower_match(<<>>, <<>>) ->
true;
lower_match(_B0, _B1) ->
false.
lower_keyfind(_K, _P, []) ->
false;
lower_keyfind(K, P, [H | T]) ->
case lower_match(K, element(P, H)) of
true ->
H;
false ->
lower_keyfind(K, P, T)
end.
-bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120430/2a4b9b69/attachment.htm>
More information about the erlang-questions
mailing list