range of ranges into one range?
Jonathan Marler via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Jun 25 23:17:07 PDT 2017
I'm using the phobos "chain" function to iterate over a set of
string arrays. However, one of the variables is actually an
array of structs that each contain a string array. So I use
"map" to get a range of string arrays, but "chain" expects each
variable to be a string array, not a range of string arrays. The
solution I came up with was to find a way to convert a range of
ranges into one range. I couldn't find this transformation in
phobos. Does anyone know if it already exists? It's actually
similar to chain itself but chains a range of ranges, not a tuple
of ranges. I implemented something that works below, but would
love to use something that already exists in phobos.
import std.stdio, std.range, std.algorithm;
struct MyStrings
{
string[] strings;
}
void main()
{
auto normalStringArray1 = ["a", "b", "c"];
auto normalStringArray2 = ["d", "e", "f"];
auto myStringArrays = [
MyStrings(["g", "h", "i"]),
MyStrings(["j", "k", "l"]),
];
foreach(str; chain(
normalStringArray1,
normalStringArray2,
splice(map!(a => a.strings)(myStringArrays))))
{
writeln(str);
}
}
auto splice(Range)(Range inputRange)
{
static struct SplicedRanges(K)
{
static assert(K.init.empty);
Range inputRange;
K current;
this(Range inputRange)
{
this.inputRange = inputRange;
if(!this.inputRange.empty)
{
current = this.inputRange.front;
if(current.empty)
{
setCurrentToNext();
}
}
}
private void setCurrentToNext()
{
while(!inputRange.empty)
{
inputRange.popFront;
if(inputRange.empty)
{
break;
}
current = inputRange.front;
if(!current.empty)
{
break;
}
}
}
@property bool empty()
{
return current.empty;
}
@property auto front()
{
return current.front;
}
void popFront()
{
if(!current.empty)
{
current.popFront;
if(!current.empty)
{
return;
}
}
setCurrentToNext();
}
}
return SplicedRanges!(typeof(inputRange.front))(inputRange);
}
More information about the Digitalmars-d-learn
mailing list