LoginSignup
6
2

More than 5 years have passed since last update.

Elixirの単独キー関数をサクッと複数キー対応する

Posted at

fukuoka.ex代表のpiacereです
今回もご覧いただいて、ありがとうございます:bow:

Elixirで関数を書いていると、Enum.drop()のような、複数キーが指定可能な処理をサクっと書きたいシチュエーションがあります

単独キーの関数を、複数キー対応することで、このコツのようなものをシェアしたいと思います

関数サンプル:マップリストを単独キー指定で文字列置換

マップリストのマップにある値を、単独キー指定で文字列置換する関数を以下のように書いてみます

defmodule MapList do
    @doc """
    Replace map value

    ## Examples
        iex> MapList.replace( [ %{ "c1" => "v1", "c2" => "v2" }, %{ "c1" => "v3", "c2" => "v4" } ], "c1", "v", "Value" )
        [ %{ "c1" => "Value1", "c2" => "v2" }, %{ "c1" => "Value3", "c2" => "v4" } ]
    """
    def replace( map_list, column, pattern, replacement ) do
        map_list |> Enum.map( fn item_map -> Map.put( item_map, column, String.replace( item_map[ column ], pattern, replacement ) ) end )
    end
end

マップリストを複数キー指定で文字列置換

上記関数を複数キー対応すると、以下のようになります

defmodule MapList do
    @doc """
    Replace map values

    ## Examples
        iex> MapList.replace( [ %{ "c1" => "v1", "c2" => "v2" }, %{ "c1" => "v3", "c2" => "v4" } ], [ "c1" ], "v", "Value" )
        [ %{ "c1" => "Value1", "c2" => "v2" }, %{ "c1" => "Value3", "c2" => "v4" } ]
        iex> MapList.replace( [ %{ "c1" => "v1", "c2" => "v2" }, %{ "c1" => "v3", "c2" => "v4" } ], [ "c1", "c2" ], "v", "Value" )
        [ %{ "c1" => "Value1", "c2" => "Value2" }, %{ "c1" => "Value3", "c2" => "Value4" } ]
    """
    def replace( map_list, columns, pattern, replacement ) do
        columns
        |> Enum.reduce( map_list, fn column, acc -> 
            acc |> Enum.map( fn item_map -> Map.put( item_map, column, String.replace( item_map[ column ], pattern, replacement ) ) end )
        end )
    end
end

ポイントは、以下5点です

  • 第2引数を、複数キー指定可能とするため、リストに変更した
  • 複数キーでEnum.reduce()を回すことで、キーの個数分、処理を繰り返すようにした
  • Enum.reduce()の初期値をmap_listとし、それをaccとして、各キーの更新を反映させた
  • マップ内で行う置換処理は、変更前と変えていない(パイプの前がmap_listからaccに変わっただけ)
  • 複数キーのテストケースを追加した ※実際はTDDしているので、先にテストから変更した

「Enum.reduce()がちょっと慣れなくて苦手」という方は、「accの初期値はmap_list」という点と、「accが繰り返し更新される」という点に着目すると、少し読みやすくなるかも知れません

p.s.「いいね」よろしくお願いします

ページ左上の image.pngimage.png のクリックを、どうぞよろしくお願いします:bow:
ここの数字が増えると、書き手としては「ウケている」という感覚が得られ、連載を更に進化させていくモチベーションになりますので、もっとElixirネタを見たいというあなた、私達と一緒に盛り上げてください!:tada:

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2