biotagging as a simple stateful filter
monkyyy
crazymonkyyy at gmail.com
Tue Jul 28 08:12:41 UTC 2026
```d
enum biotag{outside,inside,begin};
auto biomap(alias F,alias G,R)(R r){
struct map{
R r;
biotag state=biotag.outside;
auto front()=>r.front;
void popFront(){
r.popFront;
if( ! r.empty){
state=state ? G(r.front) : cast(biotag)(F(r.front)*2);
}}
bool empty()=>r.empty;
}
return map(r);
}
bool isdigit(dchar c)=>iota('0',':').canFind(c);
static assert('9'.isdigit);
biotag isdigitorsymbol(dchar c){
if(c.isdigit||c==','||c=='.'){
return biotag.inside;
}
return biotag.outside;
}
unittest{
auto r="hello, you.
123,456.789!".biomap!(isdigit,isdigitorsymbol);
while( ! r.empty){
writeln(r.front,':',r.state);
r.popFront;
}}
auto takeextra(alias F,R)(R r,int i){
struct take{
R r;
int i;
auto front()=>r.front;
void popFront(){
if(i>0){i--;}
r.popFront;
}
static if(__traits(compiles,F(r))){
bool empty()=> r.empty || i==0 && ! F(r);
} else {
bool empty()=> r.empty || i==0 && ! F(r.front);
}
}
return take(r,i);
}
unittest{
auto r=[1,2,5,6,2];
r.takeextra!(a=>a>3)(2).writeln;
r.takeextra!(a=>a.sum>10)(1).writeln;
}
auto find(alias F,R)(R r){
while( ! r.empty && ! F(r)){
r.popFront;
}
return r;
}
auto biosplit(alias F,alias G,R)(R r){
auto r_=r.biomap!(F,G);
struct split{
typeof(r_) r;
//auto
front()=>chain(r.take(1),r.drop(1).until!(a=>a.state!=biotag.inside));
auto front()=>r.takeextra!(a=>a.state==biotag.inside)(1);
void popFront(){
r.popFront;
while( ! r.empty && r.state!=biotag.begin){
r.popFront;
}}
bool empty()=>r.empty;
}
return split(r_.find!(r=>r.state==biotag.begin));
}
unittest{
"hello, im john the 3rd. I made 4$, and 100,000.01euros"
.biosplit!(isdigit,isdigitorsymbol)
.each!writeln;
}
```
Im not entire sure this is correct; and I had to fight phoboes
overly constrained type theory; but for future reference
More information about the Digitalmars-d
mailing list