SmartieHead
SmartieHead

Reputation: 63

replacing null values from in map with some other value

I have a map

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

I need to check for only empty values in this given map. if I find any key with empty value/null it should be replaced by some other value. Only null values should be changed, other values should be same

this is what i have tried.I tried doing it using for loop its working but everytime it takes a new map and i also need to store all replaced values in new map because i need to insert it in database.

suppose client_id = "ASHA14"

for {k, v} <- exchange_accounts, v == "",
  do: Map.replace!(exchange_accounts, k, client_id)

the result should be a map

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

but everytime its iterating over loop and forming a newmap

[%{"BSE" => "ASHA14", "MCX" => "", "NSE" => ""}
 %{"BSE" => "", "MCX" => "ASHA14", "NSE" => ""}
 %{"BSE" => "", "MCX" => "", "NSE" => "ASHA14"}]

Upvotes: 1

Views: 522

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

You were nearly there; while Enum.reduce/3 surely works, the more concise solution with Kernel.SpecialForms.for/1 comprehension (using into: keyword parameter to produce a map) would be:

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

The thing is for/1 just skips entries not passing any of conditions, while you need to keep them intact.

Upvotes: 1

TheAnh
TheAnh

Reputation: 2813

so what you're doing is looping over exchange_accounts with a filter v == "". It will create a new list with value from 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"}
]

What i think it should be:

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

Upvotes: 1

Related Questions