你好,我有这个结构
request = %Model{
id: 4_269_615,
site_id: 3,
user_id: 183_317,
program_id: 174,
type: %ProgramType{
value: :CASHBACK_PROGRAM,
__unknown_fields__: []
},
type_data: %ProgressProgramUser{
id: 1_336_676,
valid_stake: nil,
level: nil,
theo_ggr: nil,
__unknown_fields__: []
},
start_at: ~U[2024-09-05 13:27:20.391727Z],
end_at: nil,
inserted_at: ~U[2024-09-05 13:27:24.152602Z],
program_name: "test cb program 20 min GOLD NFT",
__unknown_fields__: []
}
我正在尝试从结构以及嵌套结构中删除
__unknown_fields__: []
。
我正在使用的代码正在运行
def drop_unknown_fields(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> drop_unknown_fields()
end
def drop_unknown_fields(%{} = map) when is_map(map) do
map
|> Enum.reduce(%{}, fn {key, value}, acc ->
updated_value =
case date?(value) do
true -> value
false -> drop_unknown_fields(value)
end
Map.put(acc, key, updated_value)
end)
|> Map.delete(:__unknown_fields__)
end
def drop_unknown_fields(value), do: value
def date?(%DateTime{}), do: true
def date?(%Date{}), do: true
def date?(%NaiveDateTime{}), do: true
def date?(_), do: false
但我认为这不是正确的做法。检查日期的原因是:当我尝试执行嵌套结构时,datatime 也是一个结构,并且它被解析为映射,这不是必需的。所以你能指导我一些最佳的方法来清理这个结构并删除
:__unknown_fields__
谢谢你
更新:我用下面的代码重构了它,但仍在寻找建议。
def drop_unknown_fields(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> only_consider_unknown_fields(struct)
|> drop_unknown_fields()
end
def drop_unknown_fields(%{} = map) when is_map(map) do
map
|> Enum.reduce(%{}, fn {key, value}, acc ->
updated_value = drop_unknown_fields(value)
Map.put(acc, key, updated_value)
end)
|> Map.delete(:__unknown_fields__)
end
def drop_unknown_fields({:consider, map}), do: drop_unknown_fields(map)
def drop_unknown_fields({:ignore, struct}), do: struct
def drop_unknown_fields(value), do: value
defp only_consider_unknown_fields(map, struct) do
case Map.has_key?(map, :__unknown_fields__) do
true -> {:consider, map}
false -> {:ignore, struct}
end
end
这是一个我认为按照您想要的方式工作的实现。
具有该特定键的结构体将转换为映射,该特定键将被删除,并且它们的值将被递归处理。
其他结构保持原样。
然后处理非结构映射的值并将其转换回映射。
任何其他值保持原样。
def drop_unknown_fields(%_{__unknown_fields__: _} = struct) do
for {k, v} <- Map.from_struct(struct), k != :__unknown_fields__, into: %{} do
{k, drop_unknown_fields(v)}
end
end
def drop_unknown_fields(%_{} = struct), do: struct
def drop_unknown_fields(%{} = map) do
for {k, v} <- map, into: %{}, do: {k, drop_unknown_fields(v)}
end
def drop_unknown_fields(value), do: value
输出:
%{
id: 4269615,
type: %{value: :CASHBACK_PROGRAM},
site_id: 3,
user_id: 183317,
program_id: 174,
type_data: %{id: 1336676, level: nil, valid_stake: nil, theo_ggr: nil},
start_at: ~U[2024-09-05 13:27:20.391727Z],
end_at: nil,
inserted_at: ~U[2024-09-05 13:27:24.152602Z],
program_name: "test cb program 20 min GOLD NFT"
}
完整代码:
defmodule Model do
defstruct [
:id,
:site_id,
:user_id,
:program_id,
:type,
:type_data,
:start_at,
:end_at,
:inserted_at,
:program_name,
:__unknown_fields__
]
end
defmodule ProgramType do
defstruct [
:value,
:__unknown_fields__
]
end
defmodule ProgressProgramUser do
defstruct [
:id,
:valid_stake,
:level,
:theo_ggr,
:__unknown_fields__
]
end
defmodule Main do
def main do
request = %Model{
id: 4_269_615,
site_id: 3,
user_id: 183_317,
program_id: 174,
type: %ProgramType{
value: :CASHBACK_PROGRAM,
__unknown_fields__: []
},
type_data: %ProgressProgramUser{
id: 1_336_676,
valid_stake: nil,
level: nil,
theo_ggr: nil,
__unknown_fields__: []
},
start_at: ~U[2024-09-05 13:27:20.391727Z],
end_at: nil,
inserted_at: ~U[2024-09-05 13:27:24.152602Z],
program_name: "test cb program 20 min GOLD NFT",
__unknown_fields__: []
}
request |> drop_unknown_fields() |> IO.inspect()
end
def drop_unknown_fields(%_{__unknown_fields__: _} = struct) do
for {k, v} <- Map.from_struct(struct), k != :__unknown_fields__, into: %{} do
{k, drop_unknown_fields(v)}
end
end
def drop_unknown_fields(%_{} = struct), do: struct
def drop_unknown_fields(%{} = map) do
for {k, v} <- map, into: %{}, do: {k, drop_unknown_fields(v)}
end
def drop_unknown_fields(value), do: value
end
Main.main()