Search code examples
elixirpattern-matchingecto

Pattern matching in a list of maps


I have a nested list of maps, and I would like to grab a specific element of a map. How can I do it?

This is my map:

[
%Eagle.Content.TemplateFields.TemplateField{
__meta__: #Ecto.Schema.Metadata<:loaded, "template_fields">,
id: 13,
inserted_at: ~N[2021-10-20 12:02:42],
name: "Meta title",
name_slug: "meta_title",
position: nil,
settings: %{"options" => [], "validate" => %{"required" => []}},
template: #Ecto.Association.NotLoaded<association :template is not loaded>,
template_id: 4,
type: "text",
updated_at: ~N[2021-10-20 12:02:42]
},
%Eagle.Content.TemplateFields.TemplateField{
__meta__: #Ecto.Schema.Metadata<:loaded, "template_fields">,
id: 14,
inserted_at: ~N[2021-10-20 12:02:42],
name: "Meta description",
name_slug: "meta_description",
position: nil,
settings: %{"options" => [], "validate" => []},
template: #Ecto.Association.NotLoaded<association :template is not loaded>,
template_id: 4,
type: "text",
updated_at: ~N[2021-10-20 12:02:42]
 }
]

And I would like to get name from second map.

For now I have something like this: x = landing_page.template.fields[%{name: "Meta description"}]

I will be grateful for help


Solution

  • You mentioned Pattern Matching. If you are looking for pattern without using the helper functions in Enum etc. Then do:

    [ a | b ] = your_value # your deeply nested data. You can ignore a or b using an _
    
    [ c ] = b # which one you want, the first or second element from your map? I chose the second "b" from above.
    
    v = c[:name] # the value of atom "name" in your deeply nested example. #=> "Meta description"
    

    Of course you can break this down to one liner but I broke it down for you, so you get the process. You can go and get more and more information like a surgeon. Oddly as it sounds, the problem is that by simplifying it can also lead to complications So avoid one liner expressions.