vida tutorial también sinonimo programación lenguaje inmortal framework buscó elixir

tutorial - elixir también se buscó



Convierte una cuerda Elixir en un entero o en un flotador (8)

Necesito convertir una cadena a un valor de punto flotante o un número entero. No hubo un método como,

string_to_integer


Además de las funciones Integer.parse/1 y Float.parse/1 que José sugirió, también puede verificar String.to_integer/1 y String.to_float/1 .

Sugerencia: vea también to_atom/1 , to_char_list/1 , to_existing_atom/1 para otras conversiones.



El problema con el uso de Integer.parse/1 es que se analizará cualquier parte no numérica de la cadena, siempre que se encuentre en el extremo posterior. Por ejemplo:

Integer.parse("01") # {1, ""} Integer.parse("01.2") # {1, ".2"} Integer.parse("0-1") # {0, "-1"} Integer.parse("-01") # {-1, ""} Integer.parse("x-01") # :error Integer.parse("0-1x") # {0, "-1x"}

Del String.to_integer/1 modo, String.to_integer/1 tiene los siguientes resultados:

String.to_integer("01") # 1 String.to_integer("01.2") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2") String.to_integer("0-1") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2") String.to_integer("-01") # -1 String.to_integer("x-01") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2") String.to_integer("0-1x") # ** (ArgumentError) argument error :erlang.binary_to_integer("01.2")

En su lugar, valide la cadena primero.

re = Regex.compile!("^[+-]?[0-9]*/.?[0-9]*$") Regex.match?(re, "01") # true Regex.match?(re, "01.2") # true Regex.match?(re, "0-1") # false Regex.match?(re, "-01") # true Regex.match?(re, "x-01") # false Regex.match?(re, "0-1x") # false

La expresión regular podría ser más simple (por ejemplo, ^[0-9]*$ ) según su caso de uso.


Gracias amigos en esta página, simplemente simplificando una respuesta aquí:

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

Gracias a @dimagog por el comentario


Hay 4 funciones para crear un número a partir de una cadena

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

String.to_integer funciona bien pero String.to_float es más difícil:

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

Como String.to_float solo puede manejar float bien formateado, p. Ej .: 1.0 , not 1 (integer). Eso fue documentado en el documento de String.to_float

Devuelve un flotante cuya representación de texto es una cadena.

cadena debe ser la representación de cadena de un flotante, incluyendo un punto decimal. Para analizar una cadena sin punto decimal como flotante, se debe usar Float.parse / 1. De lo contrario, se generará un ArgumentError.

Pero Float.parse devuelve una tupla de 2 elementos, no el número que desea, así que ponerlo en la tubería no es "genial":

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]

El uso de elem para obtener el primer elemento de la tupla lo hace más corto y más dulce:

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]


Puede convertirlo a una char_list y luego usar Erlang to_integer/1 o to_float/1 .

P.ej

iex> {myInt, _} = :string.to_integer(to_char_list("23")) {23, []} iex> myInt 23


Si desea convertir una cadena al tipo numérico que está dentro de la cadena y eliminar todos los demás caracteres, esto probablemente sea excesivo, pero devolverá un flotante si es un flotante o un int si es un int o nil si la cadena no contiene un tipo numérico

@spec string_to_numeric(binary()) :: float() | number() | nil def string_to_numeric(val) when is_binary(val), do: _string_to_numeric(Regex.replace(~r{[^/d/.]}, val, "")) defp _string_to_numeric(val) when is_binary(val), do: _string_to_numeric(Integer.parse(val), val) defp _string_to_numeric(:error, _val), do: nil defp _string_to_numeric({num, ""}, _val), do: num defp _string_to_numeric({num, ".0"}, _val), do: num defp _string_to_numeric({_num, _str}, val), do: elem(Float.parse(val), 0)


Decimal.new("1") |> Decimal.to_integer Decimal.new("1.0") |> Decimal.to_float