dpren

dpren

How to collapse/group records by id within a list of maps

Hello! I am really really new to Elixir, getting hands dirty with existing code base.

I do have a transactions object - a list of maps that is returned by an API call. Now, let’s assume this object is done this way:

[{"id":"xyz", "amount": 45.00, "description":"Una mattina mi son svegliato", "dateTime":"2022-10-06T00:00:00.000"},
{"id":"abc", "amount": 74.00, "description":"Vacationes En Chile", "dateTime":"2022-10-05T15:30:00.000"},
{"id":"xyz", "amount": 2.00, "description":"oh bella ciao", "dateTime":"2022-10-06T00:00:00.000"}
 ]

Currently, the array is streamed with stuff being done in .filter and .map method, something like this:

defp fetch_account_transactions(consent, token, account, start_from) do
    with {:ok, transactions} <-
           do_fetch_account_transactions(consent, token, account, []) do
      {
        :ok,
        transactions
        |> Stream.filter(fn data ->
          data["status"] == "BOOKED" && data["transactionMutability"] != "Mutable"
        end)
        |> Stream.map(&data_to_transaction(account, consent, &1))
      }
    end
  end

What I’d like to do is applying a transformation to transactions before it’s being streamed, such that, if something is true, I group maps in that list such that the final transactions object that gets filtered and mapped is the following:

[{"id":"xyz", "amount": 47.00, "description":"Una mattina mi son svegliato oh bella ciao", "dateTime":"2022-10-06T00:00:00.000"},
{"id":"abc", "amount": 74.00, "description":"Vacationes En Chile", "dateTime":"2022-10-05T15:30:00.000"}
 ]

that is - grouping by “id” field in maps and applying transformations such as sum(amount), min(dateTime) and concat(descriptions).

So grateful in advance for your support!

Marked As Solved

cblavier

cblavier

You can merge with a multi clause function that will handle map keys with different merge strategies : sum for amounts, concatenation for descriptions and first value for other keys

for {id, entries} <- Enum.group_by(list, & &1.id) do
  for entry <- entries, reduce: %{id: id, amount: 0, description: ""} do
    acc ->
      Map.merge(acc, entry, fn 
        :amount, amount_1, amount_2 -> amount_1 + amount_2
        :description, desc_1, desc_2 -> "#{desc_1} #{desc_2}"
        _key, _v1 = nil, v2 -> v2
        _key, v1, _v2 -> v1
      end) 
  end
end

Where Next?

Popular in Questions Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&amp;query=perfume&amp;page=2, I would like to get: ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New

Other popular topics Top

mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement