我有一张地图
exchange_accounts = %{"BSE" => "yes", "MCX" => "", "NSE" => ""}
我只需要检查给定映射中的空值。 如果我发现任何键的值为空/空,则应将其替换为其他值。只能更改空值,其他值应相同
这是我尝试过的。我尝试使用for循环来工作,但是每次需要一张新地图时,我还需要将所有替换值存储在新地图中,因为我需要将其插入数据库中。
假设client_id = "ASHA14"
for {k, v} <- exchange_accounts, v == "",
do: Map.replace!(exchange_accounts, k, client_id)
结果应为地图
%{"BSE" => "yes", "MCX" => "ASHA14", "NSE" => "ASHA14"}
但是每次循环遍历并形成新映射
[%{"BSE" => "ASHA14", "MCX" => "", "NSE" => ""}
%{"BSE" => "", "MCX" => "ASHA14", "NSE" => ""}
%{"BSE" => "", "MCX" => "", "NSE" => "ASHA14"}]
答案 0 :(得分:1)
所以您正在做的是使用过滤器exchange_accounts
遍历v == ""
。
它将创建一个新列表,其值来自Map.replace!(exchange_accounts, k, client_id)
iex()> for {k, v} <- exchange_accounts, v == "", do: Map.replace!(exchange_accounts, k, client_id)
[
%{"BSE" => "yes", "MCX" => "ASHA14", "NSE" => ""},
%{"BSE" => "yes", "MCX" => "", "NSE" => "ASHA14"}
]
我认为应该是:
Enum.reduce(exchange_accounts, %{}, fn {k, v}, acc ->
if v == "" || v == nil, do: Map.put(acc, k, client_id),
else: Map.put(acc, k, v)
end)
iex()>
%{"BSE" => "yes", "MCX" => "ASHA14", "NSE" => "ASHA14"}
答案 1 :(得分:1)
你快到那儿了;尽管Enum.reduce/3
肯定有效,但更复杂的Kernel.SpecialForms.for/1
解决方案(使用into:
关键字参数生成地图)将是:
for {k, v} <- %{"BSE" => "yes", "MCX" => "", "NSE" => ""},
do: {k, (if is_nil(v) or v == "", do: "SUBST", else: v)},
into: %{}
#⇒ %{"BSE" => "yes", "MCX" => "SUBST", "NSE" => "SUBST"}
问题是for/1
只是跳过没有通过任何条件的条目,而您需要保持它们完整。