beatscode

beatscode

Recursively accumulate nested maps

Having an issue similar to https://forum.elixirforum.net/t/whats-the-best-way-to-access-and-retrieve-data-from-deeply-nested-maps-and-lists/613/4.

I have a data structure with a nested map I’d like to accumulate into a list. The problem is I don’t know how to recursively get the maps of nested elements.
Here is a contrived version. I’m trying to get a list of all the c and nested c values. Is there a way to do this?

test "Recursive Maps" do
    #I just want all the c's in a list
    rMap = %{:a => 1, :b => 2, :c => %{ :a => 111, :b => 2222, 
        :c => %{ :a => 212, :b => 323, 
            :c => %{:a => 45, :b => 524, 
                :c => %{}}}}}

    rMap2 = %{:a => 3, :b => 4, 
        :c => %{ :a => 5, :b => 6, 
            :c => %{ :a => 7, :b => 8, 
                :c => %{:a => 9, :b => 10, 
                    :c => %{a: 11, b: 12, c: 13}}}}}
                    
    rMaps = [rMap,rMap2]
    IO.puts "rMaps List of Justcs"
    IO.inspect rMaps
    justCs = justc rMaps
    IO.inspect justCs
    
    justCs = justc3 rMaps
    IO.inspect justCs

end
# Loop through list
def justc3(rMaps) do
    Enum.reduce_while(rMaps, [], fn rMap, acc ->
        if Map.has_key?(rMap,:c) == false do
            {:halt, acc}
        else
            c = Map.get(rMap,:c)
            {:cont, [c] ++ acc} 
        end
    end)
end

def justc(rMaps) do
    justCs = for rMap <- rMaps do
        c = Map.get(rMap,:c)
      #  IO.inspect Enum.count(c)
        if Enum.count(c) == 0 do
            []
        else
            Map.get(rMap,:c) 
        end
    end
end

First Post!

amnu3387

amnu3387

Why not just divide it into two functions that match on having a :c atom (if you want to match on binary keys too, then adding another function that matches on it) and recur, returning the accumulator if no map with :c is passed?

defmodule Test do
  def get_c(acc, %{:c => c}), do: Test.get_c([c | acc], c)
  def get_c(acc, _), do: acc
end

iex(4)> defmodule Test do
...(4)> def get_c(acc, %{:c => c}), do: Test.get_c([c | acc], c)
...(4)> def get_c(acc, _), do: acc
...(4)> end

{:module, Test,
 <<70, 79, 82, 49, 0, 0, 3, 248, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 85,
   0, 0, 0, 9, 11, 69, 108, 105, 120, 105, 114, 46, 84, 101, 115, 116, 8, 95,
   95, 105, 110, 102, 111, 95, 95, 9, 102, ...>>, {:get_c, 2}}

iex(5)> Test.get_c([], %{a: 'test', c: %{a: false, b: true, c: %{c: 1, b: 2, d: 3}}})

[1, %{b: 2, c: 1, d: 3}, %{a: false, b: true, c: %{b: 2, c: 1, d: 3}}]

In case you want to customise at runtime the key that you dig for you could use a case,

def get_arbitrary(acc, %{} = map, key) do
  case map[key] do
    nil -> acc
    value -> get_arbitrary([value | acc], value, key)
  end
end
def get_arbitrary(acc, _, _), do: acc

Where Next?

Popular in Questions Top

aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement