用其他值替换地图中的空值

replacing null values from in map with some other value

我有一张地图

exchange_accounts = %{"BSE" => "yes", "MCX" => "", "NSE" => ""}

我只需要检查给定地图中的空值。 如果我发现 value/null 为空的键,则应将其替换为其他值。只应更改空值,其他值应相同

这就是我所拥有的 tried.I 尝试使用 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"}]

所以您正在做的是使用过滤器 v == "" 循环 exchange_accounts。 它将创建一个新列表,其值来自 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"}

你快到了;而 Enum.reduce/3 surely works, the more concise solution with 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 只是跳过不满足任何条件的条目,而您需要保持它们完好无损。