6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TIPS】forの多重リスト処理

Last updated at Posted at 2024-12-25

この記事は、Elixir Advent Calendar 2024 シリーズ12 の24日目です


【本コラムは、15分で読め、5分で試せます】

piacere です、ご覧いただいてありがとございます :bow:

@RyoWakabayashi さんの 配列から全順列の組み合わせを拾うコラムfor による多重リスト処理と再帰の組み合わせテクニックがあったので解説します

基本

下記は、[1, 3] の要素を1つずつ出し、そこに [2, 4] の要素を1つずつ乗算するという、for による2重リスト処理の例です

iex> for x <- [1, 2], y <- [3, 4], do: x * y
[3, 4, 6, 8]

2重だけで無い多重リストも指定可能です

iex> for x <- [1, 2], y <- [3, 4], z <- [5, 6], do: x * y * z
[15, 18, 20, 24, 30, 36, 40, 48]

変動するリストの指定

固定リストだけで無く、動的に変動するリストの指定も可能です

iex> for x <- Enum.shuffle([1, 2]), y <- Enum.shuffle([3, 4]), do: x * y
[8, 6, 3, 4]
iex> for x <- Enum.shuffle([1, 2]), y <- Enum.shuffle([3, 4]), do: x * y
[6, 8, 4, 3]
iex> for x <- Enum.shuffle([1, 2]), y <- Enum.shuffle([3, 4]), do: x * y
[6, 8, 3, 4]

要素同士が重複しない組み合わせを作る

for の2重リスト目を、y <- list -- [x] と1重リスト目の要素を除外するように作ると、1重リスト目と2重リスト目で同じ要素が出ない組み合わせを生成できます

iex> list = [1, 2, 3]
iex> for x <- list, y <- Enum.map(list -- [x], & [&1]), do: [x | y]
[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]

このように、各リストが影響し合う多重リスト処理も作れます

配列から全順列の組み合わせを拾うコラム

上記までの知識があれば、下記 @RyoWakabayashi さんの 配列から全順列の組み合わせを拾うコラム も読みこなせるようになれます

こちらのコードは、再帰の中で、再帰を繰り返し元として呼ぶ for が、下記「+」にあります

defmodule Permutations do

  def all(_, 0), do: [[]]
  def all([], _), do: []

  def all(list, n) do
    for x <- list,
        rest = list -- [x],
+       perm <- all(rest, n - 1),
      do: [x | perm]
  end
end

これを上記例と同じ書き方に改めると、こうなります

なお、削除した rest = list -- [x] のように、中間変数を定義し、多重リスト処理に利用できることも for の高度な仕様です

defmodule Permutations do

  def all(_, 0), do: [[]]
  def all([], _), do: []

  def all(list, n) do
    for x <- list,
+       perm <- all(list -- [x], n - 1),
      do: [x | perm]
  end
end

もっと同じような記述に改めると、より読みこなしやすくなるでしょう

defmodule Permutations do

  def all(_, 0), do: [[]]
  def all([], _), do: []

  def all(list, n) do
+   for x <- list, y <- all(list -- [x], n - 1), do: [x | y]
  end
end

p.s.このコラムが、面白かったり、役に立ったら…

image.png にて、どうぞ応援よろしくお願いします :bow:

6
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?