thousandsofthem
Writing idiomatic Elixir code
Trying to write good elixir code.
Input:
data = %{"a" => 0, "b" => 2, "c" => 0, "evilkey" => 666}
for specific keys i need to write some specific output if condition is true
Ruby version:
out = []
out << "text1" if data["a"] > 0
out << "text2" if data["b"] > 0
out << "text3" if data["c"] > 0
out
Ugly elixir version:
out = []
out = if data["a"] > 0 do
out ++ ["text1"]
else
out
end
...
...
out
Good elixir version: ???
Any thoughts here?
Marked As Solved
thousandsofthem
Thanks!
The solution with filters and map look about right.
Re: IO.iodata_to_binary thing - i can’t just put things together this way, but overall it looks good, just need to add |> Enum.filter(fn(x) -> !is_nil(x) end), i.e.
[
(if data["a"] > 0, do: "text1"),
(if data["b"] > 0, do: "text2"),
(if data["c"] > 0, do: "text3")
] |> Enum.filter(fn(x) -> !is_nil(x) end)
Also Liked
michalmuskala
You can do that by using if as an expression and assembling list of values finally concatenating them together:
IO.iodata_to_binary([
if(data["a"] > 0, do: "text1", else: ""),
if(data["b"] > 0, do: "text2", else: ""),
if(data["c"] > 0, do: "text3", else: "")
])
You could even extract the if to a separate function, if the pattern if very repeating:
defp if_positive(value, text), do: if(value > 0, do: text, else: "")
IO.iodata_to_binary([
if_positive(data["a"], "text1"),
if_positive(data["b"], "text2"),
if_positive(data["c"], "text3")
])
benwilson512
data
|> Enum.filter(&match?({_, v} when v > 0, &1))
|> Enum.map(fn
{"a", _} -> "text1"
{"b", _} -> "text2"
{"c", _} -> "text3"
end)
taiansu
A more functional apporach
output_texts = %{
"a" => "text1",
"b" => "text2",
"c" => "text3",
}
out = data
|> Enum.filter(fn {_, v} -> v > 0 end)
|> Enum.filter(fn {k, _} -> Enum.member(Map.keys(output_texts), k) end)
|> Enum.map(fn {k, _} -> output_texts[k] end)
|> Enum.join()
benwilson512
Also because nobody has mentioned this yet, the “ugly elixir version” is not actually an elixir version. It would not work at all because out is immutable.
thousandsofthem
It will, there are re-assignment for out:
out = if ...
out ++ ...
else
out
end
so every consequent out is different variable








