Convert Elixir string to integer or float

There are 4 functions to create number from string

  • String.to_integer, String.to_float
  • Integer.parse, Float.parse

String.to_integer works nicely but String.to_float is tougher:

iex()> "1 2 3 10 100" |> String.split |> Enum.map(&String.to_integer/1)
[1, 2, 3, 10, 100]

iex()> "1.0 1 3 10 100" |> String.split |> Enum.map(&String.to_float/1)
** (ArgumentError) argument error
    :erlang.binary_to_float("1")
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2

As String.to_float can only handle well-formatted float, e.g: 1.0, not 1 (integer). That was documented in String.to_float's doc

Returns a float whose text representation is string.

string must be the string representation of a float including a decimal point. In order to parse a string without decimal point as a float then Float.parse/1 should be used. Otherwise, an ArgumentError will be raised.

But Float.parse returns a tuple of 2 elements, not the number you want, so put it into pipeline is not "cool":

iex()> "1.0 1 3 10 100" |> String.split \
|> Enum.map(fn n -> {v, _} = Float.parse(n); v end)

[1.0, 1.0, 3.0, 10.0, 100.0]

Using elem to get first element from tuple make it shorter and sweeter:

iex()> "1.0 1 3 10 100" |> String.split \
|> Enum.map(fn n -> Float.parse(n) |> elem(0) end)

[1.0, 1.0, 3.0, 10.0, 100.0]

In addition to the Integer.parse/1 and Float.parse/1 functions which José suggested you may also check String.to_integer/1 and String.to_float/1.

Hint: See also to_atom/1,to_char_list/1,to_existing_atom/1for other conversions.


Thanks folks on this page, just simplifying an answer here:

{int_val, ""} = Integer.parse(val)

as it validates that the entire string was parsed (not just a prefix).


Check Integer.parse/1 and Float.parse/1.

Tags:

Elixir