How to implement filterMap
Christian Köstlin
christian.koestlin at gmail.com
Fri Dec 29 23:10:47 UTC 2023
Is there a way to implement filterMap (meaning do mapping of a
range, but if something happens during the map, leave this
element out of the resulting range).
I have two solutions (one is with evaluating the mapping function
several times), and one tries to store the result for the next
front call like this.
Both do not seem very clean for all possible types. Here the
version that tries to cache the mapping results.
```d
template filterMap(mapping...) if (mapping.length == 1)
{
auto filterMap(Range)(Range range)
{
import std.range : ElementType, empty;
import std.functional : unaryFun;
alias RangeElement = ElementType!Range;
alias mappingFunction = unaryFun!mapping;
typeof(mappingFunction(RangeElement.init)) result;
void findNext() {
while (!range.empty)
{
try
{
result = mappingFunction(range.front);
break;
}
catch (Exception e)
{
range.popFront;
}
}
}
findNext();
struct FilterMap
{
bool empty()
{
return range.empty;
}
auto ref front()
{
return result;
}
void popFront()
{
range.popFront;
findNext();
}
}
return FilterMap();
}
}
@("filterMap") unittest {
import std.conv : to;
import std.array : array;
["1", "2", "abc", ""].filterMap!(s => s.to!int *
2).array.should == [2, 4];
}
```
Kind regards,
Christian
More information about the Digitalmars-d-learn
mailing list