On Thursday, 30 May 2013 at 04:00:39 UTC, Jonathan M Davis wrote:
On Thursday, May 30, 2013 05:53:02 Brad Anderson wrote:
On Thursday, 30 May 2013 at 03:50:52 UTC, Brad Anderson wrote:
> Is there a simple way to consume a range apart from
> std.array.array? I don't need to result of the range stored
> in
> an array, I just need a lazy map to evaluate completely.
Obviously I could just popFront. To be more clear, I want
something like eat() or consume() or exhaust() that I can tack
on
the end of my chained algorithm calls.
If you specifically want to iterate over it, then I think that
you need to
repeatedly call popFront (or callPopFrontN if it hasLength).
However, if what
you want is for the resultant range to be empty, you can use
std.range.takeNone. If it can, it'll return the same range type
as the
original, and if it can't, it'll return takeExactly(range, 0).
- Jonathan M Davis
There was a filter in the change so I had no length. The tailing
map had a void element type which mean foreach didn't work on it.
I ended up with:
void eat(R)(R r) { while(!r.empty) { r.front; r.popFront(); } }
I was actually just playing around reimplementing Andrei's
example from his InformIT article[1] using std.algorithm and
friends. It went from:
import std.stdio, std.string;
void main() {
uint[string] dic;
foreach (line; stdin.byLine) {
// Break sentence into words
string[] words = split(strip(line));
// Add each word in the sentence to the vocabulary
foreach (word; words) {
if (word in dic) continue; // nothing to do
uint newID = dic.length;
dic[word] = newID;
writeln(newID, '\t', word);
}
}
}
to:
import std.stdio, std.algorithm, std.array;
void eat(R)(R r) { while(!r.empty) { r.front; r.popFront; } }
void main() {
size_t[dstring] dic;
stdin.byLine
.joiner(" ")
.array
.splitter(' ')
.filter!(w => !w.empty && w !in dic)
.map!(w => writeln(dic[w.idup] = dic.length, '\t', w))
.eat;
}
I would have prefered to not use joiner() but working with ranges
of ranges of ranges (splitter() on each line) got a bit weird and
confusing.
splitter() needed array slicing and length which joiner() doesn't
have so I had to use array(). I was confused about why I was
suddenly getting dchar[] out the other end but found the
StackOverflow question [2] in which you explain why joiner does
that (you really kick ass at answering StackOverflow questions,
Jonathan). Having a variant of splitter that ignores empty
tokens would be nice to have too.
1.
http://www.informit.com/articles/article.aspx?p=1381876&seqNum=4
2.
http://stackoverflow.com/questions/12288465/std-algorithm-joinerstring-string-why-result-elements-are-dchar-and-not-ch