I have a list of structs of an arbitrary size.
Let's call it l
.
l = [%X{a:1}, %X{a:3}, %X{a:9}, %X{a:11}]
The size of l
keeps changing. What I'd like to know is how do I pattern match against l
to ensure it always is made up of structs of %X{}
. I want the pattern matching to fail if the list contains something else. For example:
l = [%X{a:1}, %X{a:3}, %Y{a:9}, %Z{a:11}]
Things I've tried
i = %X{}
j = %Y{}
[%X{}|_] = [i,i,i]
But that matches only the first element.
[%X{}|_] = [i,j,j]
Should fail for my use case, but it doesn't. Maybe if there's an operator or something like this, that will match a list of specific type, that's exactly what I'm looking for:
[%X{}+] = [i,i,i] # Doesn't exist, just an example
Some background
I'm on phoenix and I have a model post
with has_many
relationship with images
. A given user could upload multiple images and I'd like to pattern match to make sure I'm working with the right struct (%Plug.Upload{}
) in this case.
Any help is much appreciated. Thanks :)
You cannot pattern match on every element of a list (without recursion). In this case I'd use Enum.all?/2
and the match?/2
macro:
if Enum.all?(list, &match?(%X{}, &1)) do
...
end
While the answer by @Dogbert is perfectly valid, I personally find the explicit clauses to be more succinct:
all_are_x =
Enum.all?(list, fn
%X{} -> true
_ -> false
end)
AFAIK, what you are looking for doesn't exist: you cannot pattern match on every element of a list.
You can use Enum.map/2, to crash at the first non %X{}
element:
Enum.map(l, &(%X{}=&1))
To pattern match, I used: %X{} = something
, while Dogbert used: match?(%X{}, &1)
The difference is that first one fails if it doesn't match, while the second one returns false
. If you want to stick to "let it crash" of elixir, you might be interested in the first one, while in most of the case you will prefer to use the second one, like this for example:
k == Enum.reject(l, &match?(%X{}=&1))
k == [] || IO.inspect(k)
Enum.reject?/2 used with match?/2 will not crash and return a list of all the element that are not an X structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With