3

I want to parse a string in Elixir. It obviously is binary. I want to get the value of left_operand, it is '2', but I am not sure how to do it. Because it's like a string, list, tuple mix stuff.

iex(13)> str = "[{\"start_usage\":\"0\",\"left_operand\":\"2\"}]"
iex(15)> is_binary str
true

The string is JSON format retrieved from MySQL. I want to use the devinus/poison module to parse it, but I'm not sure how to deal with the first and last double quotes (").

It seems that I just need the tuple part so I can do it like

iex(5)> s = Poison.Parser.parse!(~s({\"start_usage\":\"0\",\"left_operand\":\"2\"}))
%{"left_operand" => "2", "start_usage" => "0"}
iex(6)> s["left_operand"]
"2"

But I don't know how to get the tuple part.

Thanks in advance

EDIT:

I think I figured out how to do it my way.

iex> iex(4)> [s] = Poison.Parser.parse!("[{\"start_usage\":\"0\",\"left_operand\":\"2\"}]")
[%{"left_operand" => "2", "start_usage" => "0"}]
iex(5)> s
%{"left_operand" => "2", "start_usage" => "0"}
iex(6)> s["left_operand"]
"2"

I am not sure why this works, I didn't pass the ~s prefix

2 Answers 2

3

The tuple part that you are looking for is actually a map.

The reason your original version didn't work is because your JSON, when decoded, returned a map as the first element of a list.

There are multiple ways to get the first element of a list.

You can either use the hd function:

iex(2)> s = [%{"left_operand" => "2", "start_usage" => "0"}]
[%{"left_operand" => "2", "start_usage" => "0"}]
iex(3)> hd s
%{"left_operand" => "2", "start_usage" => "0"}

Or you can pattern match:

iex(4)> [s | _] = [%{"left_operand" => "2", "start_usage" => "0"}]
[%{"left_operand" => "2", "start_usage" => "0"}]
iex(5)> s
%{"left_operand" => "2", "start_usage" => "0"}

Here destructuring is used to split the list into its head and tail elements (the tail is ignored which is why _ is used)

This has nothing to do with the type of the elements inside the list. If you wanted the first 3 elements of a list, you could do:

iex(6)> [a, b, c | tail] = ["a string", %{}, 1, 5, ?s, []]
["a string", %{}, 1, 5, 115, []]
iex(7)> a
"a string"
iex(8)> b
%{}
iex(9)> c
1
iex(10)> tail
[5, 115, []] 
Sign up to request clarification or add additional context in comments.

Comments

1

When you parse a JSON string with Poison, there's no way for it to know if the values inside the JSON object are an integer or something else other than a string. To get the number 2, you can do:

~s({"start_usage":"0","left_operand":"2"})
|> Poison.Parser.parse!
|> Map.get("left_operand")
|> String.to_integer()

Comments

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.