Elixir 문자열을 정수 또는 부동 소수점으로 변환


97

문자열을 부동 소수점 값 또는 정수로 변환해야합니다. 다음과 같은 방법이 없었습니다.

string_to_integer

답변:


153

36
이것은 정수가 아닌 튜플 (성공한 경우)을 직접 반환합니다. 당신이하고 싶은 경우에 @Szymon 제즈 대답을 참조String.to_integer/1

6
사용하는 어떤 이유가 Integer.parse/1이상은 String.to_integer/1?
Ian Vaughan

10
@IanVaughan Integer.parse/1:error실패 하면 원자를 반환합니다 . String.to_integer/1던졌습니다 (FunctionClauseError).
Jonathan Soifer

52

받는 사람뿐만 아니라 Integer.parse/1Float.parse/1호세 당신도 확인할 수 있습니다 제안 기능 String.to_integer/1String.to_float/1 .

힌트 : 참조 to_atom/1, to_char_list/1, to_existing_atom/1다른 변환을 위해.


27

이 페이지의 사람들에게 감사드립니다. 여기에 답변을 단순화하십시오.

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

전체 문자열이 (단지 접두사가 아닌) 구문 분석되었는지 확인합니다.


val이 순수하게 정수가 아닌 경우 오류가 발생합니다. 변환이 성공했는지 확인하기 위해 결과에 대한 사례를 추가했습니다. 두 번째 절은 입력이 "x3"인지 "3x"인지 상관하지 않기 때문에 : error 또는 비어 있지 않은 두 번째 문자열을 잡기 위해 일반적 일 수 있습니다.
Sinc

14

문자열에서 숫자를 생성하는 4 가지 함수가 있습니다.

  • String.to_integer, String.to_float
  • 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

String.to_float: 만 예를 들어 잘 형식의 부동 소수점 처리 할 수 있습니다 1.0,하지 1(정수). 즉에 설명 된 String.to_float의 문서

텍스트 표현이 문자열 인 부동 소수점을 반환합니다.

string은 소수점을 포함하는 부동 소수점의 문자열 표현이어야합니다. 소수점이없는 문자열을 float로 구문 분석하려면 Float.parse / 1을 사용해야합니다. 그렇지 않으면 ArgumentError가 발생합니다.

그러나 Float.parse원하는 숫자가 아닌 2 개 요소의 튜플을 반환하므로 파이프 라인에 넣는 것은 "멋지다"는 것이 아닙니다.

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튜플에서 첫 번째 요소를 가져 오는 데 사용 하면 더 짧고 달콤합니다.

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]

11

char_list로 변환 한 다음 Erlang to_integer/1또는 to_float/1.

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

iex> myInt
23

기능에서 사용하는 방법? 내 최선의 해결책은 fn q -> {v, _} = Float.parse(q); v end내가 싫어하는 것입니다. Enum.map예를 들어 에서 사용하고 list |> Enum.map(&String.to_float/1)싶지만 string.to_float가 정수에 대해 작동하지 않습니까?
Zhomart

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

1
IMO 이것은 최고의 답변입니다.
Marcin Adamczyk

이 오류가 발생했습니다 : ** (UndefinedFunctionError) function Decimal.new/1 is undefined (모듈 Decimal을 사용할 수 없음)
Daniel Cukier

4

사용의 문제 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]*$사용 사례에 따라 정규 표현식이 더 간단 할 수 있습니다 (예 :) .


0

문자열을 문자열 내에있는 숫자 유형으로 변환하고 다른 모든 문자를 제거하려면 과잉 일 수 있지만 float이면 float를 반환하고 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.