Skip to content

Commit

Permalink
Merge pull request #48 from mykewould/deep_key_change
Browse files Browse the repository at this point in the history
Recursive key change for Maps
  • Loading branch information
mykewould committed Jul 31, 2015
2 parents 4966b62 + 69441c6 commit edf2637
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/crutches/map.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Crutches.Map do
@doc ~S"""
Recursively traverse a (nested) hash and change the keys based on
the function provided.
## Examples
iex> map = %{"hello" => %{"goodbye" => 1}, "akuna" => "matata"}
iex> Map.dkeys_update(map, fn (key) -> String.to_atom(key) end)
%{:hello => %{:goodbye => 1}, :akuna => "matata"}
iex> map = %{"hello" => %{"goodbye" => 1, "akuna" => "matata", "hello" => %{"goodbye" => 1, "akuna" => "matata"}}, "akuna" => "matata"}
iex> Map.dkeys_update(map, fn (key) -> String.to_atom(key) end)
%{hello: %{akuna: "matata", goodbye: 1, hello: %{akuna: "matata", goodbye: 1}}, akuna: "matata"}
"""
def dkeys_update(map, fun), do: dkeys_update(map, fun, %{})
def dkeys_update(map, _, acc) when map == %{}, do: acc
def dkeys_update(map, fun, acc) do
key = Map.keys(map) |> List.first
case is_map(map[key]) do
true -> value = dkeys_update(map[key], fun)
_ -> value = map[key]
end
dkeys_update(Map.delete(map, key), fun, Map.put(acc, fun.(key), value))
end
end
5 changes: 5 additions & 0 deletions test/crutches/map_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule Crutches.MapTest do
alias Crutches.Map
use ExUnit.Case, async: true
doctest Crutches.Map
end

0 comments on commit edf2637

Please sign in to comment.