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

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
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
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement