digitalmars.D.bugs - [Issue 13865] New: std.range.rangeSplit
- via Digitalmars-d-bugs (78/78) Dec 15 2014 https://issues.dlang.org/show_bug.cgi?id=13865
https://issues.dlang.org/show_bug.cgi?id=13865 Issue ID: 13865 Summary: std.range.rangeSplit Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: Phobos Assignee: nobody puremagic.com Reporter: bearophile_hugs eml.cc 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: 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)); } --
Dec 15 2014