DimWell
How to flatten a map?
Hi,
I am relatively new to Elixir and need a support from more advanced users.
I try to do a simple thing → Flatten Map
But Elixir and functional programming in general is a bit new to me.
I found online a solution, but it looks overcomplicated.
I wonder if maybe there is a solution out of the box provided by the language.
I tried to find something like Map.flatten(%{a: 1, %{b: 2}}) but with no success.
It would be great if you could advice that is the best practice ?
Meanwhile, I found the solution online, please see the code below.
defmodule Json do def flatten(%{} = json) do json |> Map.to_list() |> to_flat_map(%{}) end def flatten(%{} = json) when json == %{}, do: %{} defp to_flat_map([{_k, %{} = v} | t], acc), do: to_flat_map(Map.to_list(v), to_flat_map(t, acc)) defp to_flat_map([{k, v} | t], acc), do: to_flat_map(t, Map.put_new(acc, k, v)) defp to_flat_map([], acc), do: acc end %{id: "1", foo: %{bar: %{qux: "hello world"}, baz: 123}} |> Json.flatten() |> IO.inspect() # %{baz: 123, id: "1", qux: "hello world"}
Currently, due to a lack of knowledge I can’t evaluate this solution.
I would highly appreciate if someone could comment on the above code and mention good and bad points ?
Marked As Solved
benwilson512
Here is a slightly simpler implementation that you may be able to evaluate more easily:
defmodule Foo do
def flatten_map(map) when is_map(map) do
map
|> Map.to_list
|> do_flatten([])
|> Map.new
end
defp do_flatten([], acc), do: acc
defp do_flatten([{_k, v} | rest], acc) when is_map(v) do
v = Map.to_list(v)
flattened_subtree = do_flatten(v, acc)
do_flatten(flattened_subtree ++ rest, acc)
end
defp do_flatten([kv | rest], acc) do
do_flatten(rest, [kv | acc])
end
end
Also Liked
benwilson512
Can you speak a bit about your use case? What do you want to do if sub-maps include the same key as a parent map ie: %{foo: %{bar: 1}, bar: 2}
idi527
You don’t pattern match maps with %{ _k, v }, you do it with %{^k => v}.
Note the pin.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








