Simplify Pattern Matching with Map Updates

jrowah

jrowah

Created 1 month ago

Imagine you have a nested map structure representing a user with preferences:

user = %{
  id: 123,
  name: "Alice",
  preferences: %{
    theme: "dark",
    notifications: %{
      email: true,
      push: false
    }
  }
}

Traditionally, to update a deeply nested value (like turning on push notifications), you’d write:


updated_user = %{
  user | 
  preferences: %{
    user.preferences | 
    notifications: %{
      user.preferences.notifications | 
      push: true
    }
  }
}

But this gets unwieldy quickly! Elixir provides a beautiful pattern with the put_in/2 macro that makes this much cleaner:

updated_user = put_in(user, [:preferences, :notifications, :push], true)

The real magic happens when you combine this with Elixir’s Access module:

import Access

# Update all notifications at once
user = update_in(user, [:preferences, :notifications], fn notifications ->
  Map.new(notifications, fn {key, value} -> {key, true} end)
end)

# Update only specific keys in a list of maps
users = [
  %{id: 1, active: false},
  %{id: 2, active: false},
  %{id: 3, active: true}
]

# Activate users with IDs 1 and 2
activated_users = update_in(users, [all(), :active], fn active ->
  true
end)