A few days ago i was developing a JSON API on phoenix which receives users phone number from client and starts sending messages to that phone number. There was a little problem in production however.
The problem was some people used Arabic or Persian keyboards to enter their phone number. And the phone number was not passed correctly into sending message API. So i’ve developed a micro library called Numero to tackle this problem in elixir.
Thank you @Eiji for reminding me my problem with function naming. I should remove is_ from next minor version.
This example looks nice and clean but the reason i’ve done it with char list was so that i could determine utf-8 digits too (but now that is see my code i just forgotten to support utf-8 numbers ). like “۱” which is 1 in Farsi.
Dealing with binary operations is a UTF-8 string is a bit hard. and maybe ugly.
For example if i wanted to do as you did on numbers i should have done this:
defmodule Example do
@digits String.graphemes("0123456789")
def digit_only?(""), do: false
def digit_only?(string), do: do_digit_only?(string)
defp do_digit_only?(""), do: true
defp do_digit_only?(<<char::binary-size(1), rest::binary>>) when char in @digits, do: do_digit_only?(rest)
defp do_digit_only?(<<char::binary-size(2), rest::binary>>) when char in @digits, do: do_digit_only?(rest)
defp do_digit_only?(_), do: false
end
Which i think may lead to some unwanted exceptions.
I’ve been working on numero today and i did as you said and i have to say It was a significant improvement in performance and it resulted in a more beautiful code.
I tested the old version (with iteration solution) with a very long string and it took 1948ms and your suggestion made it possible to normalize the same string in only 5ms. Wow…
I knew binary pattern matching is fast in elixir but i did’t think it could improve performance this much!
So thank you for your suggestion and teaching me.
Anyways, i’d be really thankful if you can look at this code and tell me
Should is use one Enum.each/2 or using multiple ones are ok?
I’ve released Numero v0.3.0 which is much faster than 0.2.0 thanks to binary pattern matching and preventing a conversion back and forth with charlists. (Which @NobbZ suggested)
You can read release notes here if you are interested.
Thanks.
P.S the reason i changed the minor version was that there were two slight incompatibilities with previous version in Numero API.