0

If I have a JSON object where the value of a key is an array of integers, and each integer of the array just happens to correspond with the code point of a printable ASCII character, is there any way that I can have Elixir interpret the array as just a plain list of integers and not as a char list?

I've used three different Elixir JSON parsers in an attempt to get a list of integers returned, but they all return the char representation of the list:

elixir-json:

iex> JSON.decode!(~s({ "foo": [35, 35] }))
%{"foo" => '##'}

exjsx:

iex> JSX.decode!(~s({ "foo": [35, 35] }))
%{"foo" => '##'}

poison:

iex> Poison.decode!(~s({ "foo": [35, 35] }))
%{"foo" => '##'}

What I would like is just %{"foo" => [35, 35]}. Is this possible, or am I missing something? If it's not possible, how should I be decoding this value from JSON into Elixir, and then how would I encode it back into a JSON array should I need to send the JSON on to some other external system?

Edit

Thanks to michalmuskala's answer, I think something clicked, and then with some further investigation, I realised there was really nothing to worry about when it comes to the parsing JSON integer arrays in and out of Elixir:

iex> json = Poison.decode!(~s({ "foo": [35, 35] }))
%{"foo" => '##'}
iex> Poison.encode!(json)
"{\"foo\":[35,35]}"

2 Answers 2

2

The returned result is perfectly fine and correct. '##' and [35, 35] is exactly the same thing in Elixir. It's just a different way to represent the same value.

iex> [35, 35] == '##'
true
iex> inspect [35, 35]
"'##'"
iex> inspect [35, 35], char_lists: :as_lists
"[35, 35]"

This is confusing at first, but there is a strong reason behind it. Majority of Erlang libraries use lists of chars (or charlists) as strings and not binaries as Elixir. For the ease of interoperability, if a list contains only printable characters it will be, by default, printed as a single quoted string. But this does not change what data is behind it - it's only a different representation of the same value.

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

1 Comment

I think the final sentence of your answer got something to finally click in my head, so thanks very much for that!
0

It's a list:

iex(16)> '##' |> is_list
true

And you can do regular List operations on it:

iex(15)> '##' |> List.first
35

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.