didier
Map, filter and reduce
Hi there,
I want to get the average height of a given list of people. Here is the associated code :
people = [%{name: 'Mary', height: 160},
%{name: 'Paul', height: 180},
%{name: 'Hugo'}]
heights = Enum.map(people, fn person -> Map.get(person, :height) end)
heights = Enum.filter(heights, fn h -> h != nil end)
if length(heights) > 0, do: (
Enum.reduce(heights, 0, fn (h, total) -> total + h end) / length(heights)
)
Is there a better way to do this? I would like to know if there is a way to filter a list of maps by a given key (here, the height property).
Thanks,
Didier
Most Liked
rvirding
You are almost at the stage where it is easier to write the loop directly and not use Enum. ![]()
NobbZ
My professor for functional programming used to say, that “loop” is just another word for recursion ![]()
NobbZ
I’d go for roughly the following as an avg function:
def avg(list)
list
|> Enum.reduce({0, 0}, &avg/2)
|> avg_finalize
end
defp avg(x, {sum, count}), do: {sum + x, count + 1}
defp avg_finalize({sum, count}), do: sum / count
The cool thing about this is, that you only need to iterate a single time over the input list.
Currently it would fail on non-numeric input, but you can easily define appropriate guards. Adding one which does simply ignore nils should be easy.
And as a small rule of thumb, when you start chaining from one Enum-function into another, you might think about using Stream instead to reduce the number of iterations over the complete input.
But this really depends on the size of your input, if your input is short enough and the Enum-chains also, then Stream might take much more time.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








