用其他一些值替换map中的空值

时间:2019-06-24 06:32:59

标签: enums maps elixir phoenix

我有一张地图

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"}]

2 个答案:

答案 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只是跳过没有通过任何条件的条目,而您需要保持它们完整。