1

I'm dealing with a JSON API that returns a number as a string. For example "12", however, this field value could also be non-numeric, for example: "-".

I've parsed the JSON data into a map and I want to extract this field to as an integer in elixir, and then perform some operation depending on where the integer falls in a certain range.

There seem to be multiple ways to do this the two main being Integer.parse/1, which returns a tuple or :error, and String.to_integer/1, which returns the integer or raises an exception.

What is the best way to perform some operation based on where the numeric value contained inside a string falls in a certain range, handling parsing errors appropriately?

2 Answers 2

2

If one expects the value can be not an integer (under normal, not exceptional circumstances,) one should use Integer.parse/2:

analysis =
  case Integer.parse(string_value_from_json) do
    {i, ""} when i in 1..10 ->
      "integer #{i} between 1 and 10"
    {i, ""} when i in 11..20 ->
      "integer #{i} is between 11 and 20"
    {i, ""} ->
      "integer #{i} was out of range"
    _ -> "integer could not be parsed"
  end

Throwing and handling an exception should be left as a last resort and is discouraged to be used to control a flow.

Sign up to request clarification or add additional context in comments.

Comments

-1

The documentation for Integer.parse says to use String.to_integer for this purpose, so it's probably best to follow the guidelines:

If you want to convert a string-formatted integer directly to a integer, String.to_integer/1 or String.to_integer/2 can be used instead.

However, String.to_integer raises an error if the string cannot be parsed. Error cases can be caught and assigned to nil, then the result pattern-matched over:

integer_value =
  try do
    String.to_integer(string_value_from_json)
  rescue
    _ -> nil
  end

analysis =
  case integer_value do
    nil -> "integer could not be parsed"
    integer_value when integer_value in 1..10 -> "integer #{integer_value} between 1 and 10"
    integer_value when integer_value in 11..20 -> "integer #{integer_value} is between 11 and 20"
    integer_value -> "integer #{integer_value} was out of range"
  end

IO.puts analysis

2 Comments

The documentation does not say to use String.to_integer, it says “it can be used,” and in this particular case this is wrong. Throwing and handling an exception should be left as a last resort. If you expect the value to be sometimes not integer, you should use Integer.parse.
I see, I initially wanted to Integer.parse but its document persuaded me otherwise. I guess I the exceptional circumstances in this case should have been more of a deciding factor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.