Segmenting Articles of a shopping cart per SellerID

Viewed 57

Imagine you have a "shopping cart" full of items. Each item has a unique "SellerID".

Now I would like to create an order in the database PER sellerID.

That means I would have to split the shopping cart, basically an array full of items, into individual arrays, split by the respective sellerID.

Sure I can iterate over the sellerIDs and could, "if sellerID == item.sellerID populate some other array, but that's where I'm stuck right now.

With the number of individual sellerIDs within the cart, I could declare arrays before iterating on each, but that doesn't seem pragmatic to me.

As additional info: I do this with a functional programming language, there variables are "immutable", once created no longer changeable. At most you can write existing variables to other variables.

I'm also more about the principle and whether there is a pragmatic solution to this problem.

PS have personally already decided that I rewrite the shopping cart, so that there is already ordered from the beginning by seller ID, then I can create the order directly iterate over the individual seller IDs of the cart.

Still, I'm interested if there is a solution-oriented way if I haven't already sorted it by SellerID in the cart before.

So thanks in advance for thinking about it! :)

2 Answers

FWIW, here is the solution without Enum.group_by/2. Everything in enumerables might be implemented with Enum.reduce/3.

iex||1 ▸ input =
  [
    %{id: 1, title: "Article1"},
    %{id: 2, title: "Article2"},
    %{id: 3, title: "Article3"}
  ]

iex||2 ▸ Enum.reduce(input, %{}, fn %{seller_id: key} = elem, acc ->
...||2 ▸   Map.update(acc, key, [elem], & &1 ++ [elem])             
...||2 ▸ end)
%{
  2 => [%{seller_id: 2, title: "Article2"}],
  3 => [%{seller_id: 3, title: "Article1"},
        %{seller_id: 3, title: "Article3"}]
}

My data comes in like that:

[
  %{id: 1, seller_id: 3, title: "Article1", price: 33.22, etc.},
  %{id: 2, seller_id: 2, title: "Article1", price: 33.22, etc.},
  %{id: 3, seller_id: 3, title: "Article1", price: 33.22, etc.}
]

and what I’d need is something like this:

[
  %{3, [
    %{id: 1, seller_id: 3, title: "Article1", price: 33.22, etc.},
    %{id: 3, seller_id: 3, title: "Article1", price: 33.22, etc.}
  ]},
  %{2, [
    %{id: 2, seller_id: 2, title: "Article1", price: 33.22, etc.}
  ]}
]

As mentioned by Aleksei Matiushkin, Enum.group_by/2 will do the trick. I just tried it with:

Enum.group_by(articles, & &1.seller_id)

And what I get is:

%{
  2 => [
         %{id: 2, seller_id: 2, title: "Article1", price: 33.22, etc.}
  ],
  3 => [
         %{id: 1, seller_id: 3, title: "Article1", price: 33.22, etc.},
         %{id: 3, seller_id: 3, title: "Article1", price: 33.22, etc.}
  ]}

But how would I solve this if Enum.group_by/2 did not exist , or if I used a completely different language, e.g. an object-oriented programming language like Java?

I am just interested in how this would be implemented, and I do not think that it’s straightforward for me looking into the Enum.group_by/2 implementation for that.

Related