Bir dizeyi kayan nokta değerine veya tam sayıya dönüştürmem gerekiyor. Gibi bir yöntem yoktu,
string_to_integer
Yanıtlar:
Kontrol edin Integer.parse/1
ve Float.parse/1
.
Integer.parse/1
üzerinde String.to_integer/1
?
Integer.parse/1
bir :error
atom döndürür . String.to_integer/1
bir atar (FunctionClauseError)
.
Ek olarak Integer.parse/1
ve Float.parse/1
José de kontrol edebilir önerdi fonksiyonları String.to_integer/1
ve String.to_float/1
.
İpucu: Ayrıca bkz to_atom/1
, to_char_list/1
, to_existing_atom/1
diğer dönüşümler için.
Bu sayfadaki teşekkürler millet, sadece burada bir cevabı basitleştirerek:
{intVal, ""} = Integer.parse(val)
tüm dizenin ayrıştırıldığını doğrular (yalnızca bir önek değil).
Dizeden numara oluşturmak için 4 işlev vardır
String.to_integer
güzel çalışıyor ama String.to_float
daha zor:
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
: Sadece örn iyi biçimlendirilmiş float, işleyebilir 1.0
, değil 1
(tam sayı). Yani belgelenmiştir String.to_float
bireyin doc
Metin gösterimi dize olan bir kayan nokta döndürür.
dize, ondalık nokta içeren bir kayan noktanın dize temsili olmalıdır. Ondalık noktası olmayan bir dizeyi float olarak ayrıştırmak için Float.parse / 1 kullanılmalıdır. Aksi takdirde, bir ArgumentError ortaya çıkar.
Ancak Float.parse
istediğiniz sayıyı değil, 2 öğeden oluşan bir demet döndürür, bu nedenle ardışık düzene koymak "harika" değildir:
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]
elem
Tuple'dan ilk öğeyi almak için kullanmak onu daha kısa ve daha tatlı hale getirir:
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]
Bunu bir char_list'e dönüştürebilir ve ardından Erlang to_integer/1
veya to_float/1
.
Örneğin
iex> {myInt, _} = :string.to_integer(to_char_list("23"))
{23, []}
iex> myInt
23
fn q -> {v, _} = Float.parse(q); v end
sevmediğim şey. Bunu içinde kullanmayı seviyorum Enum.map
, örneğin, list |> Enum.map(&String.to_float/1)
ancak string.to_float tam sayılar için çalışmıyor mu?
Decimal.new("1") |> Decimal.to_integer
Decimal.new("1.0") |> Decimal.to_float
Kullanmanın sorunu Integer.parse/1
, kuyruk ucunda olduğu sürece dizenin sayısal olmayan herhangi bir parçasını ayrıştıracak olmasıdır. Örneğin:
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"}
Benzer şekilde String.to_integer/1
aşağıdaki sonuçlara sahiptir:
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")
Bunun yerine, önce dizeyi doğrulayın.
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
Normal ifade ^[0-9]*$
, kullanım durumunuza bağlı olarak daha basit olabilir (örneğin ).
Bir dizeyi dizenin içindeki sayısal türe dönüştürmek ve diğer tüm karakterleri kaldırmak istiyorsanız, bu muhtemelen aşırıdır, ancak bir float ise bir float veya dizede yoksa bir int veya nil ise bir int döndürür. sayısal bir tür.
@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