didier

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

rvirding

Creator of Erlang

You are almost at the stage where it is easier to write the loop directly and not use Enum. :wink:

11
Post #4
NobbZ

NobbZ

My professor for functional programming used to say, that “loop” is just another word for recursion :wink:

NobbZ

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.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

Other popular topics Top

skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

We're in Beta

About us Mission Statement