Antworten:
Überprüfen Sie Integer.parse/1
und Float.parse/1
.
Integer.parse/1
über String.to_integer/1
?
Integer.parse/1
gibt ein :error
Atom zurück, wenn dies nicht erfolgreich ist. String.to_integer/1
wirft a (FunctionClauseError)
.
Zusätzlich zu den Integer.parse/1
und Float.parse/1
Funktionen, die José vorgeschlagen hat, können Sie auch String.to_integer/1
und überprüfen String.to_float/1
.
Hinweis: Siehe auch to_atom/1
, to_char_list/1
, to_existing_atom/1
für andere Konvertierungen.
Vielen Dank Leute auf dieser Seite, die hier nur eine Antwort vereinfachen:
{intVal, ""} = Integer.parse(val)
da es bestätigt, dass die gesamte Zeichenfolge analysiert wurde (nicht nur ein Präfix).
Es gibt 4 Funktionen zum Erstellen einer Nummer aus einer Zeichenfolge
String.to_integer
funktioniert gut, String.to_float
ist aber härter:
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
Da String.to_float
kann nur gut formatiertes Float verarbeitet werden, zB: 1.0
nicht 1
(Integer). Das wurde in String.to_float
's doc dokumentiert
Gibt einen Float zurück, dessen Textdarstellung eine Zeichenfolge ist.
Zeichenfolge muss die Zeichenfolgendarstellung eines Gleitkommas einschließlich eines Dezimalpunkts sein. Um eine Zeichenfolge ohne Dezimalpunkt als Gleitkomma zu analysieren, sollte Float.parse / 1 verwendet werden. Andernfalls wird ein ArgumentError ausgelöst.
Aber Float.parse
gibt ein Tupel von zwei Elementen, nicht die Zahl , die Sie wollen, es so in Pipeline setzen ist nicht „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]
Verwenden Sie elem
, um das erste Element aus dem Tupel zu erhalten, und machen Sie es kürzer und süßer:
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]
Sie können es in eine char_list konvertieren und dann Erlang to_integer/1
oder verwenden to_float/1
.
Z.B
iex> {myInt, _} = :string.to_integer(to_char_list("23"))
{23, []}
iex> myInt
23
fn q -> {v, _} = Float.parse(q); v end
die, die ich nicht mag. Ich benutze es gerne in Enum.map
, zB list |> Enum.map(&String.to_float/1)
aber string.to_float funktioniert nicht für Ganzzahlen?
Decimal.new("1") |> Decimal.to_integer
Decimal.new("1.0") |> Decimal.to_float
Das Problem bei der Verwendung Integer.parse/1
besteht darin, dass alle nicht numerischen Teile der Zeichenfolge analysiert werden, solange sie sich am hinteren Ende befinden. Beispielsweise:
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"}
Ebenso String.to_integer/1
hat die folgenden Ergebnisse:
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")
Überprüfen Sie stattdessen zuerst die Zeichenfolge.
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
Der reguläre Ausdruck kann ^[0-9]*$
je nach Anwendungsfall einfacher sein (z. B. ).
Wenn Sie eine Zeichenfolge in einen beliebigen numerischen Typ innerhalb der Zeichenfolge konvertieren und alle anderen Zeichen entfernen möchten, ist dies wahrscheinlich ein Overkill, gibt jedoch einen Gleitkommawert zurück, wenn es sich um einen Gleitkommawert handelt, oder einen Int, wenn es sich um einen Int handelt, oder einen Nullwert, wenn der String nicht enthält ein numerischer Typ.
@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)
String.to_integer/1