Reputation: 8998
Is there an idiomatic way to calculate how many times appear the key test
in this list?
[%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}]
I would define a variable and use Enum.each
or for ->
but I know there must be a way to do it more functional.
Upvotes: 1
Views: 1202
Reputation: 121010
Just out of curiosity, exotic answer using Kernel.SpecialForms.for/1
comprehension:
String.length(
for %{"test" => _} <- [%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}],
do: <<"+">>, into: ""
)
It’s better extended to the case when we have a list of lists:
String.length(
for list <- lists, %{"test" => _} <- list, do: <<"+">>, into: ""
)
If Collectable
protocol was implemented for Integer
, it could have been written even in more concise way:
for %{"test" => _} <- [%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}],
do: 1, into: 0
But unfortunately, it does not :)
Upvotes: 2
Reputation: 222368
You can use Enum.count/2
and Map.has_key?/2
:
iex(1)> list = [%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}]
[%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}]
iex(2)> Enum.count(list, &Map.has_key?(&1, "test"))
2
As requested in comment below, here's how to count in a list of lists:
iex(3)> lists = [list, list, list]
[[%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}],
[%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}],
[%{"test" => 1}, %{"test" => 3}, %{"test2" => 1}]]
iex(4)> lists |> Enum.reduce(0, fn list, acc -> acc + Enum.count(list, &Map.has_key?(&1, "test")) end)
6
Upvotes: 3