将Elixir字符串转换为整数或浮点

将Elixir字符串转换为整数或浮点,elixir,Elixir,我需要将字符串转换为浮点值或整数。没有这样的方法, string_to_integer 您可以将其转换为字符列表,然后使用Erlang转换为\u integer/1或转换为\u float/1 例如 除了Jose建议的Integer.parse/1和Float.parse/1函数之外,还可以检查String.to_Integer/1和String.to_Float/1 提示:有关其他转换,请参见到_atom/1,到_char\u list/1,到_现有的_atom/1。谢谢本页的朋友,这里只需

我需要将字符串转换为浮点值或整数。没有这样的方法,

string_to_integer

您可以将其转换为字符列表,然后使用Erlang
转换为\u integer/1
转换为\u float/1

例如


除了Jose建议的
Integer.parse/1
Float.parse/1
函数之外,还可以检查
String.to_Integer/1
String.to_Float/1


提示:有关其他转换,请参见
到_atom/1
到_char\u list/1
到_现有的_atom/1

谢谢本页的朋友,这里只需简化一下答案:

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

当它验证整个字符串是否已被解析时(不仅仅是前缀)。

如果您想将字符串转换为字符串中的任何数字类型并删除所有其他字符,这可能有点过分,但如果它是浮点,则返回浮点;如果它是int,则返回int;如果字符串不包含数字类型,则返回nil

@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)

使用
Integer.parse/1
的问题是,它将解析字符串的任何非数字部分,只要它位于末尾。例如:

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"}
类似地,
String.to_integer/1
具有以下结果:

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")
相反,首先验证字符串

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

正则表达式可能更简单(例如,
^[0-9]*$
),具体取决于您的用例。

有4个函数可以从字符串创建数字

  • String.to_整数,String.to_浮点
  • Integer.parse,Float.parse
String.to_integer
工作得很好,但是
String.to_float
更难:

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
只能处理格式良好的float,例如:
1.0
,而不是
1
(整数)。这记录在
String.to_float
的文档中

返回文本表示为字符串的浮点值

字符串必须是包含小数点的浮点的字符串表示形式。为了将没有小数点的字符串解析为浮点,应使用float.parse/1。否则,将引发ArgumentError

但是
Float.parse
返回一个由2个元素组成的元组,而不是您想要的数字,因此将其放入管道不是“酷”:

使用
elem
从元组中获取第一个元素,可以使元组更短、更甜:

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]

请注意,这将返回一个元组(如果成功),而不是直接返回整数。如果您想这样做,请参阅@Szymon Jeż用
字符串回答。to_integer/1
是否有任何理由在
字符串上使用
integer.parse/1
。to_integer/1
?@IanVaughan
integer.parse/1
返回一个
:如果不成功,则返回一个
:error
atom
String.to_integer/1
抛出一个
(FunctionClauseError)
。要添加到Jonathan的点,
String.to_float(“0”)
抛出一个错误,而
float.parse(“0”)
返回
{0.0,“}
。这允许我在字符串可能不包含小数点时使用单个函数。如何在函数中使用它?我的最佳解决方案是
fnq->{v,{}=Float.parse(q);v end
我不喜欢。我喜欢在
Enum.map
中使用它,例如
list |>Enum.map(&String.to_float/1)
但是String.to_float不适用于整数?我认为这是最好的答案。我得到了以下错误:*(UndefinedFunctionError)函数Decimal.new/1未定义(模块Decimal不可用)如果val不是纯整数,则会引发错误。我在结果中添加了一个案例,以确保转换成功。第二个子句可以是一般的catch:error或非空的第二个字符串,因为您不太关心输入是“x3”还是“3x”。
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]
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]
Decimal.new("1") |> Decimal.to_integer
Decimal.new("1.0") |> Decimal.to_float