slouchpie

slouchpie

Efficient use of `reduce`

Imagine I have a simple list

my_list = [1, 2, 3]

and I want to “do something” to each element in a reduce loop, removing elements that error/fail while “doing something”.

It might look like this:

    my_list
    |> Enum.reduce([], fn x, acc ->
      with {:ok, result: result} <- do_something(x) do
        acc ++ [result]
      else
        _ -> acc
      end
    end)

That gets me the result I want.

However, I know that in Elixir it is more efficient to do [result] ++ acc than it is to do acc ++ [result].

So, for large lists, would it be more efficient to use [result] ++ acc in the reduce loop and then in my pipeline use Enum.reverse to put the list back in original order?

Marked As Solved

hauleth

hauleth

Well, in this case I would use Enum.flat_map/2 instead (which behind the hood will do almost the same thing you are doing there with Enum.reverse/1.

Also Liked

NobbZ

NobbZ

The most efficient version to do this is probably doing [result|acc] and Enum.reverse after building the list.

wolf4earth

wolf4earth

Alternatively to Enum.flat_map/2 you can use a for-comprehension:

for with 1-element list

for i <- my_list,
    # We have to wrap the `do_something` call in a list to use `<-` for filtering
    {:ok, result: result} <- [do_something(i)] do
  result
end

for with filter clause

for i <- my_list,
    ok_or_error = do_something(i),
    match?({:ok, _}, ok_or_error) do
  {:ok, result: result} = ok_or_error

  result
end
cloud8421

cloud8421

Note that the compiler actually replaces [hd] ++ acc with [hd | acc] (see https://erlang.org/doc/efficiency_guide/myths.html#myth--operator--++--is-always-bad) so if you try to profile both versions you might not see any difference.

Last Post!

slouchpie

slouchpie

This is equally perfect. Too many solutions 0_o

Where Next?

Trending in Questions Top

hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
Lucassifoni
Hello dear Nerves users, I’m trying to get a PWM output to show up on the 40-pin header on the MangoPI, specifically physical pin 35, or...
New
subsaharancoder
I’ve followed the Phoenix LiveView file upload code here Uploads — Phoenix LiveView v1.0.0-rc.7 and so far everything works just fine wit...
New
mnkhod
Repl driven development is so cool, like figuring out iex -S mix phx.server really changed my whole workflow. I been searching online to...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
mohsen
I’m using an Umbrella project for a Phoenix application, and I want to have one Ecto Repo and one PostgreSQL database shared by all apps....
New

Other Trending Topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
garrison
For those who are not aware, “AI agents” are, for the most part, commodity LLMs which are given access to “tools” and prompted to complet...
#ai
New
bjorng
We want to introduce a new native datatype to Erlang: native records. Although replacing all tuple records with native records is not our...
New
telnyxhiring
Introductory paragraph Telnyx is an industry leader that’s not just imagining the future of global connectivity—we’re building it. From ...
New
matt-savvy
Is there a word for the ~> symbol used in Version strings? Do you also just call it a Squiggle Arrow™ ?!
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New

We're in Beta

About us Mission Statement