# How to separate three digits of numbers

Hello friends, how can I separate three digits of numbers ?
for example
15252 => 15,252
5444785 => 5,444,785
123 => 123

Thanks

Hello and welcome,

You can separate like this in your code…

``````15_252
5_444_785
123

# example
iex(1)> 123_234 * 5_300
653140200
``````

But it’s different if You want to render those number on a web page I meant the output You might use this package…

2 Likes

If you don’t want to use an external package here is an idea:

You can compute the modulo remainder of an integer division of a power of 10 (10, 100, 1000, 10^4, …) to get an amount of digits of a number, for example:

``````iex> Integer.mod(15252, 10)
2
iex> Integer.mod(15252, 100)
52
iex> Integer.mod(15252, 1000)
252  # what you are looking for the right side
``````

For the left part you need more steps but is equaly easy:

``````iex> 15252 - Integer.mod(15252, 1000)
15000
``````

so:

``````iex> 15252 - Integer.mod(15252, 1000) |> Integer.floor_div(1000)
15
``````

Finally, convert these numbers into strings and concatenate the strings with the comma.

1 Like

Or you can play with charlists and strings, like:

``````iex> number = 15252
15252
iex> [units, tens, hundreds | reversed_tail] =  Integer.to_charlist(number) |> Enum.reverse()
'25251'
iex> Enum.reverse(reversed_tail) ++ [','] ++ [hundreds, tens, units] |> List.to_string()
"15,252"
``````
1 Like

with num being a charlist

``````def fmt(num) do
{h, t} = Enum.split(num, rem(length(num), 3))
t = t |> Enum.chunk_every(3) |> Enum.join(",")
case {h, t} do
{'', _} -> t
{_, ""} -> "#{h}"
_ -> "#{h}," <> t
end
end
``````
2 Likes

This is amazing
I thank all my friends

1 Like

Just noting that not all cultures group digits in groups of 3 (in India the first group is 2 digits, the others are 3 for example) and many countries don’t use the `,` as a grouping symbol (for example France uses a space, Germany uses a `.`). Similar considerations for the decimal separator too. number is great if you know the symbols and the grouping is regular. ex_cldr_numbers will format appropriately based on a locale (I am the author).

13 Likes

Yes, that’s right, thank you

+1 for `ex_cldr_numbers`

I like @eliottramirez solution because it is using elegant recursion. Here is my more sequential approach:

``````n = 1234567890
"#{n}"
|> to_charlist()                  # prepare data
|> Enum.reverse()                 # reverse the entire string
|> Enum.chunk_every(3)            # split in groups of 3
|> Enum.map( & Enum.reverse(&1) ) # reverse each group
|> Enum.reverse()                 # reverse the entire thing
|> Enum.join(",")                 # join with commas
"1,234,567,890"
``````

This one is longer and less elegant
but you may implement `3` and `,` as configurable.

Anyhow, my advise, when it comes to real life production, also is to use a complete solution from a package as mentioned here already.

2 Likes

You can squash `"#{n}" |> to_charlist()` into `n |> to_charlist()` or even use `n |> Integer.to_charlist()` to avoid dynamic dispatch penalty as you know that `n` is integer.

3 Likes