czrpb

czrpb

Have a Map whose values are MapSets: Best way to update?

Currently have:

keys
|> Enum.reduce(
  %{},
  fn key, acc ->
    acc
    |> Map.put(
      key,
      Map.get(acc, key, MapSet.new())
      |> MapSet.put(get_value_to_add(key))
    )
  end
)

Showing Posts 1 to 10

kokolegorille

kokolegorille

It is not very clear what You want to achieve… better put some data and expected result.

Anyway, this looks wrong (bad parens placement…)

Map.get(acc, key, MapSet.new())
      |> MapSet.put(get_value_to_add(key))

and piping once is something I try not to do. At least two pipes, otherwise I pass the parameter normally.

There is a Map.update function :slight_smile:

al2o3cr

al2o3cr

Could alternatively be spelled:

update_in acc, [Access.key(key, MapSet.new())], &MapSet.put(&1, get_value_to_add(key))
czrpb

czrpb OP

better way for updating the MapSet within the Map?

["apple", "apricot", "banana", "blueberry", "kiwi", "blackberry"]
|> Enum.reduce(
  %{},
  fn word, acc ->
    first_letter = String.at(word, 0)
    acc |> Map.put(
      first_letter,
      Map.get(acc, first_letter, MapSet.new()) |> MapSet.put(word)
    )
  end
)
|> inspect
|> IO.puts
$ elixir ~/Downloads/elixir-tmp-1.exs
%{"a" => #MapSet<["apple", "apricot"]>, "b" => #MapSet<["banana", "blackberry", "blueberry"]>, "k" => #MapSet<["kiwi"]>}
kokolegorille

kokolegorille

Except the MapSet…

iex> list = ["apple", "apricot", "banana", "blueberry", "kiwi", "blackberry"]
["apple", "apricot", "banana", "blueberry", "kiwi", "blackberry"]
iex> Enum.group_by(list, &String.first/1)
%{
  "a" => ["apple", "apricot"],
  "b" => ["banana", "blueberry", "blackberry"],
  "k" => ["kiwi"]
} 

With MapSet…

list 
|> Enum.group_by(&String.first/1) 
|> Enum.reduce(%{}, fn {k, v}, acc -> Map.put(acc, k, MapSet.new(v)) end)
%{
  "a" => #MapSet<["apple", "apricot"]>,
  "b" => #MapSet<["banana", "blackberry", "blueberry"]>,
  "k" => #MapSet<["kiwi"]>
}

With MapSet, short version :slight_smile:

iex> list 
|> Enum.group_by(&String.first/1) 
|> Enum.reduce(%{}, &Map.put(&2, elem(&1, 0), MapSet.new(elem(&1, 1))))  
%{
  "a" => #MapSet<["apple", "apricot"]>,
  "b" => #MapSet<["banana", "blackberry", "blueberry"]>,
  "k" => #MapSet<["kiwi"]>
}
ityonemo

ityonemo

A matter of personal preference, but I don’t like that reduce, because I tend to avoid using reduces unless it’s necessary, Enum.into is you much much more readable friend.

list = ["apple", "apricot", "banana", "blueberry", "kiwi", "blackberry"]

list
|> Enum.group_by(&String.first/1)
|> Enum.map(fn 
  {key, value} -> {key, Enum.into(value, MapSet.new()}
end)
|> Enum.into(%{})
kokolegorille

kokolegorille

I always think reduce is better than map into… but last time I checked with benchee, I was proved wrong :slight_smile:

ityonemo

ityonemo

I tend to do things where network is very much the bottleneck, and correctness and easy debug/read legacy code is more important, so I’ve slowly let go of caring about performance =D

My only readability concern with my code is that it’s not immediately obvious that “group_by” returns a map. so I might put a comment to that effect. Also, I’m really surprised there wasn’t a List.to_mapset…

kokolegorille

kokolegorille

At least here I prefer … MapSet.new(value) :slight_smile:

ityonemo

ityonemo

oh wow, great point. Yeah. Do that instead of my nested Enum.into monstrosity. I think I didn’t think of that because it “feels too OO”, lol.

kokolegorille

kokolegorille

That applies here too.

You could use…

|> Map.new()

…instead

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews