Skip to content

Instantly share code, notes, and snippets.

@rcdilorenzo
Last active October 25, 2021 08:19
Show Gist options
  • Save rcdilorenzo/3ae32c5e5ccc4c7ba078 to your computer and use it in GitHub Desktop.
Save rcdilorenzo/3ae32c5e5ccc4c7ba078 to your computer and use it in GitHub Desktop.
Convert a elixir json-decoded object to a map no matter how deep
defmodule JSONMapBuilder do
def to_map(list) when is_list(list) and length(list) > 0 do
case list |> List.first do
{_, _} ->
Enum.reduce(list, %{}, fn(tuple, acc) ->
{key, value} = tuple
Map.put(acc, binary_to_atom(key), to_map(value))
end)
_ ->
list
end
end
def to_map(tuple) when is_tuple(tuple) do
{key, value} = tuple
Enum.into([{binary_to_atom(key), to_map(value)}], %{})
end
def to_map(value), do: value
end
defmodule JSONMapTest do
use ExUnit.Case
alias JSONMapBuilder, as: JS
@simple_tuple [{"key", "value"}]
@simple_map %{key: "value"}
@deep_tuple [{"key1", {"key2", "value2"}}]
@deep_map %{key1: %{key2: "value2"}}
@multiple_deep_tuple [
{"key1",
[{"key2", "value2"},
{"key3", "value3"}]
},
{"another_key",
{"another_key2",
{"another_value", "another_values_value"}
}
}
]
@multiple_deep_map %{key1: %{key2: "value2", key3: "value3"}, another_key: %{another_key2: %{another_value: "another_values_value"}}}
test "converts tuple to map with one level deep" do
assert JS.to_map(@simple_tuple) == @simple_map
end
test "converts tuple to map with two levels" do
assert JS.to_map(@deep_tuple) == @deep_map
end
test "converts tuple with multiple values and keys with multiple levels" do
assert JS.to_map(@multiple_deep_tuple) == @multiple_deep_map
end
test "doesn't convert an empty list into a map when converting" do
assert JS.to_map([{"key", []}]) == %{key: []}
end
test "doesn't convert an list of non-tuples into a map when converting" do
assert JS.to_map([{"key", [1, 2, 3]}]) == %{key: [1, 2, 3]}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment