こんにちは!
プログラミング未経験文系出身、Elixirの国に迷い込んだ?!見習いアルケミストのaliceと申します。
前回まではEctoスキーマの要素として、マップが1件取り出せた前提でnameの値を取り出したり更新しました。
しかし実際には複数件のデータがリスト内の要素としてマップの形(あるいはその逆)をとって存在していることが殆どです。
ゆえに今回からはこの形をしたデータ...マップリストの値の操作について学んだことをまとめたいと思います。
目次
1.Ectoスキーマからパターンマッチを使用してパラメータを取り出す
2.Ectoスキーマからパラメータを取り出して更新する(iex内のみ)
3.Enum.mapの紹介(本記事)
4.Enum.filterの紹介
5.String.contains?の紹介
6.Enum.intoの紹介
7.Map.putの紹介
8.(番外編)元データがマップ→リスト→マップのもう一段深い入れ子構造だったらどうするか?(Map.getの紹介)
目的
リストの要素がマップ(あるいはその逆)になっている場合に値を取り出して操作できるようになりたい。
実行環境
Windows 11 + WSL2 + Ubuntu 22.04
Elixir v1.14.3
Erlang v26.0.2
Phoenix v1.7.10
今回やりたいこと
下記のマップリストから、:id
と:name
だけを取り出したい。
iex(1)> users = Nov11.Users.list_users
[debug] QUERY OK source="users" db=6.6ms decode=1.4ms queue=1.6ms idle=185.6ms
SELECT u0."id", u0."name", u0."age", u0."inserted_at", u0."updated_at" FROM "users" AS u0 []
↳ :erl_eval.do_apply/7, at: erl_eval.erl:746
[
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 1,
name: "hogehoge",
age: 10,
inserted_at: ~U[2023-11-11 14:34:43Z],
updated_at: ~U[2023-11-11 14:34:43Z]
},
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 4,
name: "fugafuga",
age: 20,
inserted_at: ~U[2023-12-06 00:15:28Z],
updated_at: ~U[2023-12-06 00:15:28Z]
},
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 5,
name: "piyopiyo",
age: 30,
inserted_at: ~U[2023-12-06 00:15:35Z],
updated_at: ~U[2023-12-06 00:15:35Z]
}
]
Enum.mapとは
Enum.mapは要素を一つずつ取り出して関数処理してリスト化して出力します。
Enum.mapの挙動の確認
まずは 第二引数をfn x -> x end
と書いて、第一引数がそのまま出力結果になっていることを確認します。
Enum.map(users, fn x -> x end)
[
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 1,
name: "hogehoge",
age: 10,
inserted_at: ~U[2023-11-11 14:34:43Z],
updated_at: ~U[2023-11-11 14:34:43Z]
},
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 4,
name: "fugafuga",
age: 20,
inserted_at: ~U[2023-12-06 00:15:28Z],
updated_at: ~U[2023-12-06 00:15:28Z]
},
%Nov11.Users.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 5,
name: "piyopiyo",
age: 30,
inserted_at: ~U[2023-12-06 00:15:35Z],
updated_at: ~U[2023-12-06 00:15:35Z]
}
]
:id
とname
だけを取り出す
Enum.mapの関数処理部分に:id
とname
だけを取り出す処理を書き加えます。
results = Enum.map(users, fn user -> {user.id, user.name} end)
[{1, "hogehoge"}, {4, "fugafuga"}, {5, "piyopiyo"}]
パイプ演算子+無名関数の略記をするとこうなります。
results = users |> Enum.map(&{&1.id, &1.name})
[{1, "hogehoge"}, {4, "fugafuga"}, {5, "piyopiyo"}]
:id
と:name
だけを取り出すことができました(^▽^)/
~Elixirの国のご案内~
↓Elixirって何ぞや?と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます
↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ!私もエンジニア未経験から学習中です。
↓We Are The Alchemists, my friends!1
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。2
-
@torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。 ↩