Elixir:从嵌套结构中提取数据的最佳实践
在Elixir中,我们可以使用Elixir:从嵌套结构中提取数据的最佳实践,elixir,Elixir,在Elixir中,我们可以使用 data = %{field: %{other_field: 1}} data[:field][:other_field] 如果它包含列表,也可以使用 data = %{field: %{other_field: [1]}} get_in data, [:field, :other_field, Access.at(0)] 但是,如果data.field.other_字段是一个结构,那么如何获取该数据呢? 上述两种方法都会失败,因为结构不实现Access.fe
data = %{field: %{other_field: 1}}
data[:field][:other_field]
如果它包含列表,也可以使用
data = %{field: %{other_field: [1]}}
get_in data, [:field, :other_field, Access.at(0)]
但是,如果data.field.other_字段是一个结构,那么如何获取该数据呢?
上述两种方法都会失败,因为结构不实现Access.fetch/2
data = %{field: %{other_field: %Struct{a: 1}}}
那么除了模式匹配之外,访问嵌套结构数据的正确方法是什么呢?使用:
键(键,默认\\nil)
访问映射/结构中的给定键
如果密钥不存在或访问的值为nil
,则使用默认值
为此,我使用ruby的try操作符实现
@spec try(Access.t(), nonempty_list(node) | atom, term) :: term
def try(data, keys, default \\ nil)
def try(nil, _keys, default), do: default
def try(data, keys, default) when is_atom(keys) do
try(data, [keys], default)
end
def try(data, keys, default) when length(keys) == 1 do
get_in(data, [Access.key(hd(keys), default)])
end
def try(data, keys, default) do
get_in(data, [Access.key(hd(keys))])
|> try(tl(keys), default)
end
示例中的用法
try(data, [:field, :other_field, :a]) # with default nil
try(data, [:field, :other_field, :a], 42) # with default 42
try(data, :single_field_as_atom) # with a single value
try(data, [:field, :other_field, :a]) # with default nil
try(data, [:field, :other_field, :a], 42) # with default 42
try(data, :single_field_as_atom) # with a single value