假设我有一个函数可以给我一个UUIDv4。
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
密钥,那将非常有用。
答案 0 :(得分:1)
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"
}
]
}
}
}
}
}
]
}
运行以下内容:
UuidConsistencyEnforcer.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"
}