是否可以选择在get_in/2
中添加默认回退值?
情景:
merge_maps = get_in(
payload, ["msg", "clicks"]
) ++ get_in(
payload, ["msg", "opens"]
)
如果在嵌套的"clicks"
地图中找不到密钥"opens"
或"msg"
,get_in/2
将返回nil
,然后会抛出错误:
** (ArgumentError) argument error
:erlang.++(nil, nil)
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5
(iex) lib/iex/evaluator.ex:230: IEx.Evaluator.do_eval/3
(iex) lib/iex/evaluator.ex:208: IEx.Evaluator.eval/3
(iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1
(iex) lib/iex/evaluator.ex:24: IEx.Evaluator.init/4
能够做类似
的事情会很高兴get_in(payload, ["msg", "clicks"], [])
如果找不到具有该键的值,则空列表将是后备值。什么是实现这一目标的正确方法?
更新
感谢@PatNowak的回答,我实现了get_in
的包装:
defmodule Helpers.AccessHelper do
def get_in_attempt(data, keys, default \\ []) do
case get_in(data, keys) do
nil -> default
result -> result
end
end
end
然后在另一个文件中:
import Helpers.AccessHelper, only: [get_in_attempt: 2]
merge_maps = get_in_attempt(
payload, ["msg", "clicks"]
) ++ get_in_attempt(
payload, ["msg", "opens"]
)
答案 0 :(得分:1)
您可以为Kernel.get_in/2
编写自己的包装器,但使用默认值作为后备。
def get_in_attempt(data, keys, default) do
case get_in(data, keys) do
nil-> default
result -> result
end
end
所以在你的情况下,它足以拥有
def get_in_attempt(data, keys) do
case get_in(data, keys) do
nil-> [] # your default is set, so don't need to pass it
result -> result
end
end
但是,使用第一种方法(使用显式default
参数)更灵活,可以在不同的场景中重复使用。)
答案 1 :(得分:0)
另一种方法,您可以使用SP_names
运算符(doc)。
Declare @max varchar(50)
Declare @min varchar(50)
select @min = min(convert(DATE, date, 104)) from table4
select @max = max(convert(DATE, date, 104)) from table4
select @max as Recent_Date,@min as Oldest_Date
因此,如果||
返回nil,则merge_maps = (get_in(
payload, ["msg", "clicks"]
) || [] ) ++ ( get_in(
payload, ["msg", "opens"]
) || [] )
会被选择为默认值
答案 2 :(得分:0)
我认为您想在这种情况下使用Access.key/2
。 Kernel.get_in
中的键可以是函数,因此您可以使用Access函数交换出字符串键列表(如果找不到该键,Access.key/2
支持默认值)。
类似这样的东西:
get_in(payload, ["msg", Access.key("clicks", []))