2016-04-29 5 views
0

Gegeben eine Liste von Elementen, wie können wir für eine bestimmte Struktur filtern?ELIXIR: wie man eine Liste für eine spezifische Struktur filtert

Beispiel:

Wir brauchen nur %TL.DocumentAttributeFilename{} aus den Elementen in der Liste

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{}] 

Antwort

6

Sie for dafür verwenden können:

Gegeben:

defmodule A do 
    defstruct [letter: :a] 
end 

defmodule B do 
    defstruct [letter: :b] 
end 

Sie können tun, :

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}] 

Dies funktioniert, weil for alle Elemente ignoriert, die nicht mit dem angegebenen Muster übereinstimmen.

+0

brillant, dank –

0

Sie auch Enum.filter verwenden können, um zu verdeutlichen, welche Operation stattfindet:

Enum.filter(lst1, fn(x) -> %TL.DocumentAttributeFilename{} == x end) 

Wie Dogbert der obige Ausdruck beobachtet nur die Elemente von lst1 halten, die TL.DocumentAttributeFilename structs mit Standardfeldwerte sind - nicht das, was Sie gefragt.

Hier ist eine Version, die alle TL.DocumentAttributeFilename structs von lst1 halten:

Enum.filter(lst1, fn(x) -> x.__struct__ == TL.DocumentAttributeFilename end) 
+2

Dies wird nur überein, wenn 'X' hat die Standardwerte für alle Felder der Struktur 'TL.DocumentAttributeFilename'. – Dogbert