Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse string in Elixir

Tags:

string

elixir

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

like image 531
王志軍 Avatar asked Nov 18 '25 21:11

王志軍


2 Answers

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, []] 
like image 114
Gazler Avatar answered Nov 22 '25 04:11

Gazler


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()
like image 35
Gjaldon Avatar answered Nov 22 '25 04:11

Gjaldon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!