# Given an integer, produce a list of its digits

I need to turn an integer into a list of digits.

For example, given `1234` as input, the output should be `[1, 2, 3, 4]`.

I am doing this right now, but it looks ugly and might even be inefficient.

``````  def get_check_digit(digits) when is_binary(digits) or is_integer(digits) do
digits
|> to_charlist()
|> Enum.map(fn char ->
{integer, []} = :string.to_integer([char])
integer
end)
|> get_check_digit()
end

def get_check_digit(digits) when is_list(digits) do
...
end
``````

Any tips?

How about Integer.digits/2 ?

4 Likes

Nice! Thanks

1 Like

`Integer.digits/2` is certainly the easiest way to do this but I took a stab at this and wrote two versions:

## Make use of codepoints

The first version is super short and basically makes use of the fact that `charlist`s boil down to a list of integers (where the characters have their corresponding ASCII values).

``````iex> 1234 |> to_charlist() |> Enum.map(& &1 - ?0)
[1, 2, 3, 4]
``````

By converting the number to a charlist, we have a list of codepoints. From here we can subtract the codepoint value of 0 (`?0` which is 48) to get the actual numerical value.

## Use math and recursion

The second solution uses a combination of integer division and the modulo operation. But see for yourself:

``````defmodule Digits do
def digits(number) when number < 0, do: digits(-number)

def digits(number) when is_integer(number) do
calc(number, [])
end

defp calc(digit, digits)
when digit < 10,
do: [digit | digits]

defp calc(number, digits) do
digit = Integer.mod(number, 10)

number
|> div(10)
|> calc([digit | digits])
end
end

IO.inspect Digits.digits(1234), charlists: :as_lists
``````

Here we get a single digit by doing `number % 10` (which is `Integer.mod/2` in Elixir), then we do the same for the next digit by dividing through 10. If we reach anything smaller than 10 we add it to the list and were done.

4 Likes

Am I missing something here? Isn’t `:erlang.integer_to_list/1/2` the easiest and fastest? Though it would give a “bad” error value if the argument is not an integer.

1 Like

Aaaaagh. I’m just now getting back into this ecosystem after a long hiatus. My search game is very weak right now.

`:erlang.integer_to_list` returns charlist

``````> :erlang.integer_to_list(123123)
'123123'
> Integer.digits(123123)
[1, 2, 3, 1, 2, 3]
``````
1 Like

Yes, I realised that later. 1 Like