shahryarjb

shahryarjb

Hi friends, I have a nested list that is unstructured, and I really know how much it has nested list or map in itself.

I just need to search and get all :tag key in this list and check the selected name by my user exists there or it is unique.

For example:

[
  %{
    children: [
      %{
        children: [],
        id: "fcfb1066-6e16-4a84-81e0-7746f12b7e76",
        tag: "test1",
        type: "section"
      },
      %{
        id: "035ca737-2cc2-488b-83f5-fe7cc2becc5e",
        parent_id: "a9963499-f6a4-4a32-bafa-aa22a9b059bc",
      },
      %{
        children: [
          %{
            other: [
              %{
                id: "035ca737-2cc2-488b-83f5-fe7cc2becc5e",
                parent_id: "a9963499-f6a4-4a32-bafa-aa22a9b059bc",
              },
            ],
            tag: "test4",
          },
        ],
        id: "8a9f0126-33a0-4c03-8c4a-5507f0562c8a",
        index: 2,
        parent: "layout",
        parent_id: "a9963499-f6a4-4a32-bafa-aa22a9b059bc",
        tag: "test2",
        type: "section"
      }
    ],
    parent: "dragLocation",
    parent_id: "dragLocation",
    tag: "test3",
  }
]

This list has no a structure that helps me to use Enum.

So I try to use macro, but based on my little knowledge I could not to find all :tag, see this code please

defmacro get_tags(data, selected_name) do
  quote do
    data = unquote(data)
    data_string = inspect(data, charlists: :as_strings)
    ast = Code.string_to_quoted(data_string)
    
    ....
  end
end

the ast = Code.string_to_quoted(data_string) passes me a nested list again, and I don’t know how to create a pattern to get tag, so after that I use to List.flatten ast but I got this error:
** (FunctionClauseError) no function clause matching in :lists.flatten/1

because It has maps in its list

Please help me to learn more about macro and search like this in a list, Thank you in advance.

Showing Posts 1 to 10

tcoopman

tcoopman

I don’t understand why you want to use a macro to solve this.

What I’d suggest is a recursive search.

shahryarjb

shahryarjb OP

Hi @tcoopman, Thank you for response

The first reason is to learn more about macros and second one is I try recursive function to find all tag in a list, but it needs so much condition to find it is map? Or list of it is so enumerable it and find map or list again so get tag etc.

Because the list I get from a user is not a structured list, and maybe it has multiple layers in only one parameter

do you have any suggestion about it, like sample code or sth?

tcoopman

tcoopman

This is something that should work:

  def find([], tags), do: tags

  def find([hd | tl], tags) do
    tag = Map.get(hd, :tag)
    tags = if tag, do: [tag | tags], else: tags

    child = Map.get(hd, :children)
    tags = if child, do: find(child, tags), else: tags

    find(tl, tags)
  end
shahryarjb

shahryarjb OP

Yes, I wrote something before like this, but as I said it has more complicity for me because maybe we have no children sometimes we have a single map into another map that has tag or childrent name is something like other

  def get_tags(data) do
    get_tags_helper(data, %{})
    |> Map.values()
    |> Enum.uniq()
  end

  defp get_tags_helper(data, tags) do
    case data do
      [] -> tags
      [head | tail] ->
        case head[:tag] do
          nil -> get_tags_helper(head[:children] ++ tail, tags)
          tag ->
            new_tags = Map.update(tags, tag, 1, &(&1 + 1))
            get_tags_helper(head[:children] ++ tail, new_tags)
        end
      _ -> tags
    end
  end

But thank you, the recursive is my selected option, at least. If you have an idea with macro, please let me know, I really want to improve my level in meta programming. :rose:

tcoopman

tcoopman

I’m not very fluent with macros either. Having said that, I really don’t see how macros are going to help you with the problem at hand.
Macros are not something you should just reach to, they are powerful but also add complexity. So only use them when necessary.

Back to your problem:
If there are no children, or no tags, my solution handles that.
If the children is not named children, how do you know it’s something you should decent into?
What is the actual problem you’re trying to solve?

shahryarjb

shahryarjb OP

Yes, I pointed out exactly this problem at the beginning of the project, but now this decision has been made at higher levels than me
Unfortunately, we have a list that different people in different organizations add a series of parameters to this list based on their taste.
All I have to do is find all the tags and check if the new name I want to insert has already been inserted.

It should be noted, sometimes some added list has no tag that should be avoided or skipped. This is true for children.
I tried to do it with the search string and check it is included whether there is, for example, tag: name or not, but sometimes I need to take this tag and make some changes on it.

That’s why I tried to move this whole list of strings to the macro and check each and every line of it.

tcoopman

tcoopman

Macros are not magic. They won’t lower the complexity of the problem.
What I would do is write test cases for the different kinds of inputs you need to handle and then implement code for them.

LostKobrakai

LostKobrakai

Macros are for turning one piece of “pseudo” code into another piece of code. That’s useful if you know some information at compile time, which you can then turn into more/different code. You don’t seem to have any information at runtime, which would help you solve the problem at hand.

hst337

hst337

Use Pathex

import Pathex.Combinator
import Pathex.Lenses
import Pathex

tag_lens =
  combine(fn rec ->
    path(:tag, :map) ||| (star() ~> rec)
  end)

Pathex.view(nested_stuff, tag_lens ~> matching("test2"))
hst337

hst337

For the future questions, if you want to traverse nested structures, just use lenses. This is a very powerful tool which solves the problems in a few lines

It is like writing a filesystem path, but for elixir structures

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews