minhajuddin

minhajuddin

Is there a simpler way to generate ids

I am using the code below to generate room ids:

reservations = [%{rooms: 1},
                %{rooms: 2},
                %{rooms: 3}]

{reservations_with_room_numbers, _} =
  Enum.reduce(reservations, {[], 0}, fn reservation, {acc, offset} ->
    upper_limit = offset+reservation.rooms - 1
  room_numbers = Enum.to_list(offset..upper_limit)
  reservation_with_room_numbers = Map.put(reservation, :room_numbers, room_numbers)
  {[reservation_with_room_numbers|acc], upper_limit + 1}
end)

IO.inspect Enum.reverse(reservations_with_room_numbers)
# =>
# [
# %{room_numbers: [0], rooms: 1}
# %{room_numbers: [1, 2], rooms: 2},
# %{room_numbers: [3, 4, 5], rooms: 3},
# ]

The code above seems too complicated for such a simple task, Is there a simpler way to do the same?

System.unique_integer [:monotonic, :positive] gives out unique integers starting at 1, However there is no way to reset it after the generation is done, so that it starts from 1 for the next call.

Marked As Solved

josevalim

josevalim

Creator of Elixir

I believe your initial solution looks good, I would just use map_reduce instead of reduce to clean things up:

reservations = [%{rooms: 1},
                %{rooms: 2},
                %{rooms: 3}]

{reservations_with_room_numbers, _} =
  Enum.map_reduce(reservations, 0, fn reservation, offset ->
    upper_limit = offset+reservation.rooms - 1
    room_numbers = Enum.to_list(offset..upper_limit)
    reservation_with_room_numbers = Map.put(reservation, :room_numbers, room_numbers)
    {reservation_with_room_numbers, upper_limit + 1}
  end)

Also Liked

JEG2

JEG2

Author of Designing Elixir Systems with OTP

Or, with a generator:

defmodule Generator do
  def new(start) do
    Agent.start_link(fn -> start end)
  end

  def next(generator) do
    Agent.get_and_update(generator, fn value -> {value, value + 1} end)
  end
end

defmodule RoomBuilder do
  def build([{:rooms, n} | rooms], built, generator) do
    room_numbers =
      Stream.repeatedly(fn -> Generator.next(generator) end)
      |> Enum.take(n)
    build(rooms, [room_numbers | built], generator)
  end
  def build([ ], built, _generator), do: Enum.reverse(built)
end

{:ok, generator} = Generator.new(0)
reservations = [rooms: 1, rooms: 2, rooms: 3]
RoomBuilder.build(reservations, [ ], generator)
|> IO.inspect
benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

One thing that isn’t clear is if we want a pure or impure solution. The original post had both. They’re wildly different solutions and people need to be aware of that.

michalmuskala

michalmuskala

I believe this shows another use case for a function like Stream.split/2 - similar to Enum.split/2, but one that would leave the “rest” part as a stream. This would allow for the most natural way to solve this:

ids = Stream.itrerate(1, &(&1 + 1))
Enum.map_reduce(reservations, ids, fn reservation, ids ->
  {room_numbers, rest} = Stream.split(ids, reservation.rooms)
  {Map.put(reservation, :room_numbers, room_numbers), rest}
end) |> elem(0)

Where Next?

Popular in Questions Top

albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
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
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
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
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
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
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
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

Other popular topics Top

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
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
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 43591 214
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
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
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
RisingFromAshes
I've read in another post that it may be possible with a router helper - but I couldn't find an appropriate one, and tbh, I'm still just ...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126226 1237
New

We're in Beta

About us Mission Statement