#naming #elixirlang Map을 합치고 싶을 때, 쓰는 Enum.into와 Map.merge

less than 1 minute read

map을 합치고 싶을 때, Map.merge/2 함수 또는 Enum.into/2 함수를 사용할 수 있다. Enum.into/2 함수는 모듈 이름처럼 더 범용적이다. map뿐만 아니라 다른 자료구조에도 사용할 수 있다.

iex> Enum.into(%{a: 1, b: 2}, %{a: 3, b: 4})
%{a: 1, b: 2}
iex> Map.merge(%{a: 1, b: 2}, %{a: 3, b: 4})
%{a: 3, b: 4}

재미있는 건 방향성이다. Enum.into/2 함수는 key가 같을 때, 왼쪽 인자로 덮어쓴다. Map.merge/2 함수는 반대다. 오른쪽 인자로 덮어쓴다.

def user_fixture(attrs \\ %{}) do
  {:ok, user} =
    attrs
    |> Enum.into(%{
        name: "Some User",
        username: "user#{System.unique_integer([:positive])}",
        password: attrs[:password] || "supersecret"})
    |> Accounts.register_user()

    user
end

Programming Phoenix 1.4 책에서 본 소스 코드다. Enum.into/2 함수는 파이프 연산자(pipe operator)와 잘 어울린다. 데이터를 변환(transform)하는 과정에서는 key가 같을 때, 왼쪽 인자로 덮어쓰는 게 자연스럽다.

네이밍도 자연스럽다. Enum.into/2 함수는 왼쪽 인자를 오른쪽 인자에 덮어쓴다. Map.merge/2 함수는 오른쪽 인자를 왼쪽 인자에 덮어쓴다.

PS: 만약 key가 중복됐을 때, 다른 처리를 해주고 싶다면 Map.merge/3 함수를 사용하면 된다.