ELIXIR:如何筛选特定结构的列表

Cha*_*gwu 1 list elixir pattern-matching

给定项目列表,我们如何过滤特定结构?

例:

我们只需%TL.DocumentAttributeFilename{}要从列表中的项目

 lst1 = [%TL.DocumentAttributeImageSize{h: 1280, w: 960}, %TL.DocumentAttributeFilename{file_name: "422305695_81769.jpg"}]
 lst2 = [%TL.DocumentAttributeVideo{duration: 7, h: 224, w: 264}, %TL.DocumentAttributeFilename{file_name: "animation.gif.mp4"}, %TL.DocumentAttributeAnimated{}]
Run Code Online (Sandbox Code Playgroud)

Dog*_*ert 7

你可以使用for这个:

鉴于:

defmodule A do
  defstruct [letter: :a]
end

defmodule B do
  defstruct [letter: :b]
end
Run Code Online (Sandbox Code Playgroud)

你可以做:

iex(1)> list = [%A{}, %B{}, %A{}, %A{}, %B{}]
[%A{letter: :a}, %B{letter: :b}, %A{letter: :a}, %A{letter: :a}, %B{letter: :b}]
iex(2)> for %A{} = a <- list, do: a
[%A{letter: :a}, %A{letter: :a}, %A{letter: :a}]
Run Code Online (Sandbox Code Playgroud)

这样做是因为for忽略了与给定模式不匹配的所有项目.


Yur*_*uri 5

您还可以使用Enum.filter具有多个主体的函数进行模式匹配:

list = [%A{number: 1}, %B{number: 2}, %A{number: 3}, %A{number: 4}, %B{number: 5}, %A{number: 6}]

Enum.filter(list, fn
  %A{} -> true
  _ -> false
end)
Run Code Online (Sandbox Code Playgroud)

这特别有用,因为您可以使用项目的属性和防护进一步缩小范围:

Enum.filter(list, fn
  %A{number: n} when n > 4 -> rem(n, 3) == 0
  %B{number: n} when n < 2 -> true
  _ -> false
end)
Run Code Online (Sandbox Code Playgroud)