Match a vector with specified length
Match a vector with specified length
I want to define a function parameter which has to be a 3D- or any-dimensional vector.
1. Just three elements
1. Just three elements
The pattern {_,_,_} partially fulfills the task:
In[]:=
{MatchQ[{1,2,3},{_,_,_}],MatchQ[{1,2,3,4},{_,_,_}]}
Out[]=
{True,False}
But it does not test the list to be a vector:
In[]:=
MatchQ[{1,{2a},3},{_,_,_}]
Out[]=
True
2. Vector with three elements
2. Vector with three elements
VectorQ has to be added as a condition: v:{_,_,_}/;VectorQ[v]
In[]:=
MatchQ[{1,2,3},v:{_,_,_}/;VectorQ[v]]
Out[]=
True
In[]:=
{MatchQ[{1,2,3},v:{_,_,_}/;VectorQ[v]],MatchQ[{1,{2a},3},v:{_,_,_}/;VectorQ[v]],MatchQ[{1,2,3,4},v:{_,_,_}/;VectorQ[v]]}
Out[]=
{True,False,False}
In[]:=
Trace[MatchQ[{1,{2a},3},v:{_,_,_}/;VectorQ[v]]]
Out[]=
{MatchQ[{1,{2a},3},v:{_,_,_}/;VectorQ[v]],{VectorQ[{1,{2a},3}],False},False}
3a. Vector with n elements - Condition
3a. Vector with n elements - Condition
If the expression is to be a vector of greater length, methods 1 and 2 are no longer practical nor readable. We try to test the length n explicitly by using v:_/;(VectorQ[v]&&Length[v]==n):
In[]:=
{MatchQ[{1,2,3,4,5},v:_/;(VectorQ[v]&&Length[v]==5)],MatchQ[{1,{2a},3,4,5},v:_/;(VectorQ[v]&&Length[v]==5)],MatchQ[{1,2,3,4,5,6},v:_/;(VectorQ[v]&&Length[v]==5)]}
Out[]=
{True,False,False}
This works.
3b. Vector with n elements - Pattern & Condition
3b. Vector with n elements - Pattern & Condition
Alternatively, we can insert the VectorQ test directly into the pattern and test the length as a condition: v:_?VectorQ/;Length[v]==n. This works as well:
In[]:=
{MatchQ[{1,2,3,4,5},v:_?VectorQ/;Length[v]==5],MatchQ[{1,{2a},3,4,5},v:_?VectorQ/;Length[v]==5],MatchQ[{1,2,3,4,5,6},v:_?VectorQ/;Length[v]==5]}
Out[]=
{True,False,False}
In[]:=
Trace[MatchQ[{1,2,3,4,5},v:_?VectorQ/;Length[v]==5]]
Out[]=
{MatchQ[{1,2,3,4,5},v:_?VectorQ/;Length[v]5],{VectorQ[{1,2,3,4,5}],True},{{Length[{1,2,3,4,5}],5},55,True},True}
In[]:=
Trace[MatchQ[{1,{2a},3,4,5},v:_?VectorQ/;Length[v]==5]]
Out[]=
{MatchQ[{1,{2a},3,4,5},v:_?VectorQ/;Length[v]5],{VectorQ[{1,{2a},3,4,5}],False},False}
4a. Numeric vector with n elements - Condition
4a. Numeric vector with n elements - Condition
If we want to additionally test for numerical values, we can accommodate this in the VectorQ test: v:_/;(VectorQ[v,NumericQ]&&Length[v]==n):
In[]:=
Clear[b];{MatchQ[{1,2,3,4,5},v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)],MatchQ[{1,πSqrt[3],3,4,5},v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)],MatchQ[{1,{2a},3,4,5},v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)],MatchQ[{1,2b,3,4,5},v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)],MatchQ[{1,2,3,4,5,6},v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)]}
Out[]=
{True,True,False,False,False}
4b. Numeric vector with n elements - Pattern & Condition
4b. Numeric vector with n elements - Pattern & Condition
I could not find how to achieve this by something like v:_?VectorQ[_,NumericQ]/;Length[v]==n
Summary
Summary
Define functions f3 and f3N which take a (numeric) 3D-Vector (Method 2):
In[]:=
ClearAll[f3,f3N];f3[v:{_,_,_}/;VectorQ[v]]:=Style["f3 OK",Blue,Bold];f3N[v:{_,_,_}/;VectorQ[v,NumericQ]]:=Style["f3N OK",Blue,Bold];
In[]:=
a=Sqrt[2];b=.;Do[Print["v = ",Style[v,Bold],", {f3[v],f3N[v]} = ",{f3[v],f3N[v]}];,{v,{{1,a,3},{1,a,b},{1,{2a},3},{1,a,3,4}}}];
v = 1,
2
,3, {f3[v],f3N[v]} = {f3 OK,f3N OK}v = 1,
2
,b, {f3[v],f3N[v]} = f3 OK,f3N1,2
,bv = 1,2
2
,3, {f3[v],f3N[v]} = f31,{22
},3,f3N1,{22
},3v = 1,
2
,3,4, {f3[v],f3N[v]} = f31,2
,3,4,f3N1,2
,3,4Define functions f and fN which take a (numeric) 5D-Vector (Methods 3a and 4a):
In[]:=
ClearAll[f,fN];f[v:_/;(VectorQ[v]&&Length[v]==5)]:=Style["f OK",Blue,Bold];fN[v:_/;(VectorQ[v,NumericQ]&&Length[v]==5)]:=Style["fN OK",Blue,Bold];
In[]:=
a=Sqrt[2];b=.;Do[Print["v = ",Style[v,Bold],", {f[v],fN[v]} = ",{f[v],fN[v]}];,{v,{{1,a,3,4,5},{1,a,b,4,5},{1,{2a},3,4,5},{1,a,3,4}}}];
v = 1,
2
,3,4,5, {f[v],fN[v]} = {f OK,fN OK}v = 1,
2
,b,4,5, {f[v],fN[v]} = f OK,fN1,2
,b,4,5v = 1,2
2
,3,4,5, {f[v],fN[v]} = f1,{22
},3,4,5,fN1,{22
},3,4,5v = 1,
2
,3,4, {f[v],fN[v]} = f1,2
,3,4,fN1,2
,3,4Question
Question
Does anyone have simpler patterns than these?