stevensonmt

stevensonmt

Map.intersection/2?

Has anyone else ever wanted to merge two maps, but have the resulting map only include keys common to both maps? I think of it as analogous to MapSet.intersection but with a function for handling the values.

m1 = %{a: 1, b:2}
m2 = %{b: 3, c:4}
Map.intersection(m1, m2, fn _k, v1, v2 -> v1 * v2 end)
> %{b: 6}

This would replace

Map.merge(m1, m2, fn _k , v1, v2 -> v1 * v2 end) 
|> Enum.filter(fn {k,_v} -> [m1, m2] |> Enum.all?(&Map.has_key?(&1, k)) end)
|> Map.new()
>%{b: 6}

Thoughts?

Most Liked

adamu

adamu

:maps.intersect(m1, m2)
%{b: 3}

:maps.intersect_with(fn _k , v1, v2 -> v1 * v2 end, m1, m2)
%{b: 6}
josevalim

josevalim

Creator of Elixir

Elixir main requires Erlang/OTP 24. Therefore if someone wants to submit a PR that adds intersect/2 and intersect/3, it will be welcome.

rvirding

rvirding

Creator of Erlang

There is only ONE type of map in the BEAM. The maps in Elixir are exactly the same maps as in Erlang. Seeing Erlang is the base language on the BEAM Elixir could not have had maps before the BEAM and Erlang implemented them.

iex(1)> m1 = %{a: 1, b: 1, c: 1}
%{a: 1, b: 1, c: 1}
iex(2)> m2 = %{a: 2 , c: 2, d: 2}
%{a: 2, c: 2, d: 2}
iex(3)> mi = :maps.intersect(m1, m2)
%{a: 2, c: 2}
iex(4)> :io.write(m1)       
#{a => 1,b => 1,c => 1}:ok
iex(5)> :io.write(m2)
#{a => 2,c => 2,d => 2}:ok
iex(6)> :io.write(m1)               
#{a => 1,b => 1,c => 1}:ok

The :io.write function is an output function in the Erlang io module and prints the maps which shows they are the same maps as in Erlang.

The :maps.intersect/2 function first came in OTP 24.0 so it may not be used yet in the Map module.

adamu

adamu

Just in case anybody has ideas:

Eiji

Eiji

All you have to do is a simple reducer. :smiling_imp:

defmodule Example do
  @spec sample(map(), map(), (Map.key(), Map.value(), Map.value() -> Map.value())) :: map()
  def sample(left, right, func) when is_map(left) and is_map(right) and is_function(func, 3) do
    Enum.reduce(left, %{}, fn
      {key, value}, acc when is_map_key(right, key) ->
        Map.put(acc, key, func.(key, value, right[key]))

      _pair, acc ->
        acc
    end)
  end
end

iex> Example.sample(%{a: 1, b: 2}, %{b: 3, c: 4}, fn _k, v1, v2 -> v1 * v2 end)
%{b: 6}

Helpful resources:

  1. Guides |> Typespecs @ Elixir documentation
  2. Enum.reduce/3
  3. Kernel.is_function/2
  4. Kernel.is_map/1
  5. Kernel.is_map_key/2
  6. Map.put/3

Where Next?

Popular in Discussions Top

krainboltgreene
Today I noticed that when defining a embeds_many the new struct has a default of [] which is confusing since: You can have jsonb[] colu...
New
AstonJ
A recent chat with @leifericf inspired this thread - he’s worked in the gaming industry, and so it got me wondering what kind of industri...
New
josefrichter
Has anyone tried Github Speckit or similar projects like AgentOS, BMAD, etc.? They basically offer a bit more structure in context windo...
New
billylanchantin
If you’re not familiar with this fun bit of math lore, Paul Erdős, the famously eccentric, peripatetic and prolific 20th-century mathem...
New
markmark206
Every time I build a web app, I worry about a bunch of basic things (persisting data, knowing when to compute which things, keeping thing...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
travisf
In upgrading from Ecto 2 to Ecto 3 I’m dealing with a failing test. If I use ExMachina build(:address) I’ll get an error trying to put_e...
New
bartblast
It’s time to implement JavaScript interop for Hologram! Eventually, there will be Hologram wrappers for most APIs, but sometimes we’ll n...
New
kusokuzeshiki
I tried to generate pages with claude code and fluxon ui. I ask to claude code to generate real world page samples, the results are thes...
New
AstonJ
There seems to be a lot of buzz around DeepSeek at the moment, with some saying it’s a ChatGPT killer. The most remarkable thing (if they...
New

Other popular topics Top

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
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
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
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
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement