17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Elixir 1.3でAccessモジュールに入る関数

Last updated at Posted at 2016-05-26

ブログから転載。


先ほどこんなTweetを見た。

%{languages: [%{name: "elixir", type: "functional"}, %{name: "c", type: "procedural"}]}
|> update_in([:languages, Access.all(), :name], &String.upcase/1)

こうすると、

%{languages: [%{name: "ELIXIR", type: "functiocal"}, %{name: "C", type: "procedural"}]}

というmapが得られる。Tweetの例にはname: "john"がいるけど紛らわしいので消した。

見慣れないAccess.all/0が使われていて、:languagesキーに対応するリストの全要素にアクセスしている。

今日の時点では他にもAccess.key/2Access.key!/1Access.elem/1が追加されている。追加されたコミットは464d3ddで、10689f4Access.fieldAccess.keyに変更されている模様。

Access.key/2は、これまで

update_in(map, [:name], &String.upcase/1)

と書いていたものを

update_in(map, [Access.key(:name, "john")], &String.upcase/1)

と書くことで、map:nameキーが無かった場合のデフォルト値を指定できる。

Access.key!/1は、キーが存在しないときに即座にraiseする。

update_in(%{color: "red"}, [Access.key!(:name)], &String.upcase/1)
** (KeyError) key :name not found in: %{color: "red"}

Access.elem/1は、

get_in({:ok, 3}, [Access.elem(1)])  #=> 3

のように、タプルにindexでアクセスできる。

感想

get_inupdate_inは確かに便利なんだろうなと思っていたけれどイマイチ活用できた記憶がない。今回の変更でかなり柔軟になったので、活躍の場が増えるのでは。

例えば以下のデータがあったとする。

users = %{users: [
  %User{name: "John", posts: [%Post{title: "foo", tags: ["elixir", "Ecto"]}]},
  %User{name: "Mary", posts: [%Post{title: "bar", tags: ["BEAM"]}, %Post{title: "baz"}]},
]}

タグは全て小文字にしておきたいな〜と思ったら次のようにすればOK。

update_in(users, [:users, Access.all(), :posts, Access.all(), Access.key(:tags, []), Access.all], &String.downcase/1)

戻り値は

%{users: [
  %User{name: "John", posts: [%Post{tags: ["elixir", "ecto"], title: "foo"}]},
  %User{name: "Mary", posts: [%Post{tags: ["beam"], title: "bar"}, %Post{tags: [], title: "baz"}]}
]}
17
16
2

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
17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?