Elixir:迭代嵌套映射并在每个级别上插入键值对
假设我有一个函数,它给我一个UUIDv4Elixir:迭代嵌套映射并在每个级别上插入键值对,elixir,Elixir,假设我有一个函数,它给我一个UUIDv4 def get_uuid() do # do magic end 我有一个嵌套映射,可以是n级深度: map = %{ name: "Alice", friends: [ %{ uid: "EXISTINGUID", name: "Betty" }, %{ name: "Bob", job: "Truck driver" } ] } 如何遍历整个映射,并在
def get_uuid() do
# do magic
end
我有一个嵌套映射,可以是n级深度:
map = %{
name: "Alice",
friends: [
%{
uid: "EXISTINGUID",
name: "Betty"
},
%{
name: "Bob",
job: "Truck driver"
}
]
}
如何遍历整个映射,并在每个级别上确保有一个键uid
,如果没有,则使用调用的值get_uuid()
插入它
预期结果:
map = %{
name: "Alice",
uid: "NEWUUID",
friends: [
%{
uid: "EXISTINGUUID",
name: "Betty"
},
%{
uid: "ANOTHERNEWUUID"
name: "Bob",
job: "Truck driver"
}
]
}
如果不具备查找现有uid
键的条件,这将非常有用
defmodule Uuid do
def generate(), do: :some_uuid
end
defmodule UuidConsistencyEnforcer do
@uuid_key :uid
def run(some_list) when is_list(some_list), do: Enum.map(some_list, &run/1)
def run(some_map) when is_map(some_map) do
some_map
|> Map.update(@uuid_key, Uuid.generate(), fn existing_uuid -> existing_uuid end)
|> Enum.reduce(%{}, fn
{key, a_map = %{}}, a -> Map.merge(a, %{key => run(a_map)})
{key, not_a_map}, a -> Map.merge(a, %{key => run(not_a_map)})
end)
end
def run(some_value), do: some_value
end
要测试:
给定一个深度嵌套的映射,例如:
map = %{
name: "Alice",
uid: "NEWUUID",
friends: [
%{
uid: "EXISTINGUUID",
name: "Betty"
},
%{
name: "Bob",
job: "Truck driver"
},
%{
n1: %{
n2: %{
n3: %{
n4: %{
name: "Alice",
uid: "NEWUUID",
friends: [
%{
uid: "EXISTINGUUID",
name: "Betty"
},
%{
name: "Bob",
job: "Truck driver"
}
]
}
}
}
}
}
]
}
运行以下命令:
uuidconsistentyenforcer.run(map)
将呈现:
%{
friends: [
%{name: "Betty", uid: "EXISTINGUUID"},
%{job: "Truck driver", name: "Bob", uid: :some_uuid},
%{
n1: %{
n2: %{
n3: %{
n4: %{
friends: [
%{name: "Betty", uid: "EXISTINGUUID"},
%{job: "Truck driver", name: "Bob", uid: :some_uuid}
],
name: "Alice",
uid: "NEWUUID"
},
uid: :some_uuid
},
uid: :some_uuid
},
uid: :some_uuid
},
uid: :some_uuid
}
],
name: "Alice",
uid: "NEWUUID"
}
为了解释
元组
等,您需要在模块
中相应地添加run/1
函数。谢谢唯一一件事:使用Uuid作为模块名会从Elixir中产生一个错误。它不应该给您一个错误。我能够复制粘贴,就像在iex中一样。您看到的错误到底是什么,可能您已经在某处定义了一个名为Uuid的库。[error]加载~/app/\u build/dev/lib/Uuid/ebin/Elixir.Uuid.beam失败::badfile[error]beam/beam\u load.c(1412):加载模块“Elixir.Uuid”时出错:目标代码中的模块名称为Elixir.Uuid
您是否可以将代码复制粘贴到此处,就像在新的iex
中一样(例如,不要在现有项目中进行iex-S混合
)?