Bug 13865 – std.range.rangeSplit

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-12-15T13:19:38Z
Last change time
2018-03-31T15:45:55Z
Assigned to
No Owner
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2014-12-15T13:19:38Z
I suggest to add to Phobos a range similar to the "tee" function of the Python itertools: https://docs.python.org/2/library/itertools.html#itertools.tee http://code.activestate.com/recipes/305588-simple-example-to-show-off-itertoolstee/ http://discontinuously.com/2012/06/inside-python-tee/ - - - - - - - - The Python description: itertools.tee(iterable[, n=2]) Return n independent iterators from a single iterable. Equivalent to: def tee(iterable, n=2): it = iter(iterable) deques = [collections.deque() for i in range(n)] def gen(mydeque): while True: if not mydeque: # when the local deque is empty newval = next(it) # fetch a new value and for d in deques: # load it to all the deques d.append(newval) yield mydeque.popleft() return tuple(gen(d) for d in deques) - - - - - - - - A bare-bones implementation in D (this is not meant to be the efficient and reliable implementation for Phobos): import std.traits: hasIndirections; import std.concurrency: Generator, yield; import std.range: ElementType; import std.algorithm: map; import std.array: array; import queue_usage2: GrowableCircularQueue; auto rangeDup(R)(R seq, in uint n=2) { alias T = ElementType!R; auto deques = new GrowableCircularQueue!T[n]; auto gen(ref GrowableCircularQueue!T mydeque) { return new Generator!T({ while (true) { if (mydeque.empty) { auto newVal = seq.front; seq.popFront; foreach (ref d; deques) d.push(newVal); } yield(mydeque.pop); } }); } return deques.map!gen.array; } // An usage example: enum sternBrocot = () => new Generator!uint({ GrowableCircularQueue!uint sb; sb.push(1u); sb.push(1u); while (true) { sb.push(sb[0] + sb[1]); sb.push(sb[1]); yield(sb.pop); } }); void main() { import std.stdio, std.range, std.algorithm, std.numeric; auto ss = rangeDup(sternBrocot()); ss[1].popFront; assert(zip(ss[0], ss[1]).take(1_000).all!(t => gcd(t[0], t[1]) == 1)); }
Comment #1 by greensunny12 — 2018-03-31T15:45:55Z
This has been added a long time ago: https://github.com/dlang/phobos/pull/1965