Skip to content

Instantly share code, notes, and snippets.

@adamzaninovich
Last active May 28, 2024 15:01
Show Gist options
  • Save adamzaninovich/348c811a47604464c9aa200a6092870c to your computer and use it in GitHub Desktop.
Save adamzaninovich/348c811a47604464c9aa200a6092870c to your computer and use it in GitHub Desktop.
Elixir implementation of this codewars kata: http://www.codewars.com/kata/521a849a05dd182a09000043/train/ruby
defmodule FlattenedMap do
def flatten(%{} = map) do
map |> Enum.map(&merge/1) |> List.flatten |> Enum.into(%{})
end
defp merge({prefix, %{} = map}), do: Enum.map(map, &do_merge(prefix, &1))
defp merge(flat), do: flat
defp do_merge(prefix, {key, val}), do: merge({merge_keys(prefix, key), val})
defp merge_keys(prefix, key) when is_atom(prefix) and is_atom(key) do
String.to_atom("#{prefix}_#{key}")
end
defp merge_keys(prefix, key), do: "#{prefix}_#{key}"
end
ExUnit.start
defmodule FlattenedMapTest do
use ExUnit.Case, async: true
test "it doesn't change an unnested map" do
map = %{id: 1, name: "example"}
assert FlattenedMap.flatten(map) == map
end
test "it flattens a nested map" do
map = %{id: 1, info: %{name: "example"}}
flat = FlattenedMap.flatten(map)
assert flat == %{id: 1, info_name: "example"}
end
test "it flattens a deeply nested map" do
map = %{id: 1, info: %{name: "example", more_info: %{count: 1}}}
flat = FlattenedMap.flatten(map)
assert flat == %{id: 1, info_name: "example", info_more_info_count: 1}
end
test "it keeps string keys as strings" do
map = %{id: 1, info: %{"name" => "example"}}
flat = FlattenedMap.flatten(map)
assert flat == %{:id => 1, "info_name" => "example"}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment