shahryarjb
Find a specific string in an unstructured and nested list
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.
Most Liked
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?
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.
hst337
tcoopman
I don’t understand why you want to use a macro to solve this.
What I’d suggest is a recursive search.
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








