Given a list L
.
It is mathematically proven that there is no element in L
matching 2 or more patterns in patt1/patt2/patt3/patt4/.../patt10
. (Note that one can express a criteria/test into a pattern. I think it is safe to think as 'criteria' instead of 'pattern', if you want.)
Now I want get
positions matching patt1,
positions matching patt2,
positions matching patt3,
positions matching patt4,
...
positions matching patt10.
One method is
{Position[L,patt1],Position[L,patt2],Position[L,patt3],...,Position[L,patt10]}
But, it looks for each element 10 times.
Maybe we can increase the performance by
- get positions matching patt1
- except positions matching patt1, get positions matching patt2.
- except positions matching patt1,2, get positions matching patt3.
- except positions matching patt1,2,3, get positions matching patt4. ...
- except positions matching patt1,2,3,...,10 get positions matching patt10.
Or we may increase the performance by..
'take the first element of L, check whether it matches patt1,patt2,patt3,patt4,...,patt10 in order. If it matched patt3, for example, then record 'the first element of L matched patt3' and then go to the next element. Check whether it matches patt1,patt2,patt3,patt4,...,patt10 in order. This time, for example, it doesn't match any pattern. Then go to the next element. It goes on like this.
The question is related to the built-in command GatherBy
, but for GatherBy
, we cannot restrict the range of values. (always all values.) And the output of GatherBy
does not show values.
First I am not sure which method is the best (Because thinking and reality are always different.) Considering the performance, are there any commonly used techniques for these problem?
I made a problem in a hurry to give an example :
A = RandomInteger[{1, 100}, 1000];
B = RandomInteger[100, #] & /@ A;
The problem is :
Select level-1 positions in B, whose length is 2
Select level-1 positions in B, whose length is 3
Select level-1 positions in B, whose length is 5
Select level-1 positions in B, whose length is 7
...
Select level-1 positions in B, whose length is 97
There may be much better example though.
Replace[L, {patt1 -> 1, patt2->2, ...}, {1}]
$\endgroup$