benonymus

benonymus

Merging maps in list based on matching value

Hey I have a list of maps, and those maps are items such:

[
%purchase{
    amount: #Decimal<2.0>,
    command: "buy",
    id: 71,
    price: #Decimal<90.394>,
  },
%purchase{
    amount: #Decimal<1.0>,
    command: "buy",
    id: 72,
    price: #Decimal<90.394>,
  }
]

As you can see the prices are the same but the amount isn’t how would you go through the list to merge the items with the same price to get something like this:

[
%purchase{
    amount: #Decimal<3.0>,
    command: "buy",
    price: #Decimal<90.394>,
  }
]

Marked As Solved

benonymus

benonymus

Hey, I came up with 2 solutions so far:

for order <- buy do
      Enum.reduce(
        buy,
        order,
        fn x, y ->
          cond do
            Decimal.cmp(x.price, y.price) == :eq and x.id != y.id ->
              new_amount = Decimal.add(x.amount, y.amount)
              Map.put(y, :amount, new_amount)

            true ->
              y
          end
        end
      )
    end
    |> Enum.uniq_by(fn x -> x.price end)

and

    for order <- buy do
      Enum.map(buy, fn x ->
        cond do
          Decimal.cmp(x.price, order.price) == :eq and x.id != order.id ->
            new_amount = Decimal.add(x.amount, order.amount)
            Map.put(order, :amount, new_amount)

          true ->
            order
        end
      end)
    end
    |> List.flatten()
    |> Enum.uniq_by(fn x -> x.price end)

But I am having a hard time deciding which one to stick with :confounded:
Edit:
I decided to stick with the reduce version, so I don’t need to flatten a list

Also Liked

dimitarvp

dimitarvp

Needlessly verbose IMO. Here’s how I went about it:

defmodule Stock do
  def aggregate_by_price(items) do
    items
    |> Enum.group_by(&(Decimal.reduce(&1.price)))
    |> Enum.map(fn({_price, items}) ->
      Enum.reduce(items, fn(acc, item) ->
        %{acc | amount: Decimal.add(acc.amount, item.amount)}
      end)
    end)
  end
end

Then in iex:

items = [
  %{price: Decimal.from_float(90.394), amount: Decimal.from_float(2.0)},
  %{price: Decimal.from_float(90.394), amount: Decimal.from_float(1.0)},
  %{price: Decimal.from_float(17.64738), amount: Decimal.from_float(10.0)},
  %{price: Decimal.from_float(90.394), amount: Decimal.from_float(5.0)},
  %{price: Decimal.from_float(17.64738), amount: Decimal.from_float(13.0)}
]

Stock.aggregate_by_price(items)

This returns:

[
  %{amount: #Decimal<8.0>, price: #Decimal<90.394>},
  %{amount: #Decimal<23.0>, price: #Decimal<17.64738>}
]

Which seems to be what you need.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
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
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
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
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
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
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 49522 488
New
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
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
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
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New

We're in Beta

About us Mission Statement