Hello friends, I have a list that I want to update it (3 level nested), and I need your suggestion to create better code
The list
elements = [
%{
children: [
%{
children: [
%{
children: [],
class: ["text-black", "w-full", "p-2"],
id: "c9ea0fff-1ee0-407e-8b2a-64afc954c40b",
index: 0,
parent: "section",
parent_id: "62197198-e3a1-46de-8f18-f2c6843f646f",
type: "text"
},
%{
children: [],
class: ["text-black", "w-full", "p-2"],
id: "b2a6b171-26e1-4e8a-8cd3-c41f388de6e8",
index: 1,
parent: "section",
parent_id: "62197198-e3a1-46de-8f18-f2c6843f646f",
type: "text"
}
],
class: ["flex", "flex-col", "justify-between", "items-stretch",
"min-h-[200px]", "w-full", "border", "border-dashed",
"border-gray-400", "p-1"],
id: "62197198-e3a1-46de-8f18-f2c6843f646f",
index: 0,
parent: "layout",
parent_id: "64a2c3f2-d71f-464a-8318-be072d7b6624",
type: "section"
}
],
class: ["flex", "flex-row", "justify-start", "items-center", "w-full",
"space-x-3", "px-3", "py-10"],
id: "64a2c3f2-d71f-464a-8318-be072d7b6624",
index: 0,
parent: "dragLocation",
parent_id: "dragLocation",
type: "layout"
}
]
for updating and adding tag to the text element I did like this, but it is very dirty I think:
def add_tag(elements, id, parent_id, layout_id, tag, type) when type in @elements do
Enum.map(elements, fn
%{type: "layout", id: ^layout_id, children: children} = selected_layout ->
edited_list =
children
|> Enum.map(fn
%{type: "section", id: ^parent_id, children: children} = selected_section ->
element_edited_list =
Enum.map(children, fn
%{type: ^type, id: ^id} = selected_element ->
Map.merge(selected_element, %{tag: tag})
element ->
element
end)
%{selected_section | children: element_edited_list}
section ->
section
end)
%{selected_layout | children: edited_list}
layout ->
layout
end)
end
MishkaTemplateCreatorWeb.MishkaCoreComponent.add_tag(elements, "c9ea0fff-1ee0-407e-8b2a-64afc954c40b", "62197198-e3a1-46de-8f18-f2c6843f646f", "64a2c3f2-d71f-464a-8318-be072d7b6624", "test1", "text")
By the way, for finding I created this code:
def find_element(elements, id, parent_id, layout_id, type) when type in @elements do
Enum.flat_map(elements, fn
%{type: "layout", id: ^layout_id, children: children} ->
case Enum.find(children, &(&1.id == parent_id)) do
nil ->
[]
%{type: "section", id: ^parent_id, children: children} ->
if is_nil(data = Enum.find(children, &(&1.id == id))), do: [], else: [data]
end
_layout ->
[]
end)
|> List.first()
end
Thank you in advance