[ https://issues.apache.org/jira/browse/GROOVY-11603?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King updated GROOVY-11603: ------------------------------- Issue Type: New Feature (was: Improvement) > Add Lazy generators for iterators > --------------------------------- > > Key: GROOVY-11603 > URL: https://issues.apache.org/jira/browse/GROOVY-11603 > Project: Groovy > Issue Type: New Feature > Reporter: Paul King > Assignee: Paul King > Priority: Major > Fix For: 5.0.0-beta-1 > > > This issue is to propose some iterate, generate and combine methods. The > first two are exact mirrors of their Stream counterparts. > {code:groovy} > def evens = Iterators.iterate(2, n -> n + 2) > def odds = Iterators.iterate(1, n -> n + 2) > assert evens.take(4).collect() == [2, 4, 6, 8] > assert odds.take(4).collect() == [1, 3, 5, 7] > var r = new Random() > var randomDigits = Iterators.generate({ r.nextInt(10) } as Supplier) > println randomDigits.take(10).join() // 2698715440 (different every time) > assert randomDigits.take(3).collect() ==~ /\[\d, \d, \d\]/ // regex of 3 > digits > {code} > We could achieve the same result using the Streams API as follows: > {code:groovy} > def alsoEvens = Stream.iterate(2, n -> n + 2).iterator() > assert alsoEvens.take(4).collect() == [2, 4, 6, 8] > {code} > So, these two methods are "just" convenience without the overhead of setting > up the Stream, so will be quicker for many simple cases. > The other methods are combine and combineLazy. They are iterator variants of > combinations/eachCombination with some inspiration from the Groovy-stream > project to use a map to name the streams/result tuples. This is also known as > cross-product and Groovy-stream calls dubs its take on cross product as faux > list-comprehension which is something we have wanted for a while. > {code:groovy} > assert Iterators.combine(x: 1..2, y: 'a'..'c').collect().toString() > == '[[x:1, y:a], [x:1, y:b], [x:1, y:c], [x:2, y:a], [x:2, y:b], [x:2, > y:c]]' > assert Iterators.combine(x: 1..3, y: 'a'..'b').collect().toString() > == '[[x:1, y:a], [x:1, y:b], [x:2, y:a], [x:2, y:b], [x:3, y:a], [x:3, > y:b]]' > {code} > The combineLazy method is the same but expects iterators as the input sources > not iterables. The traditional cross-product output would not be very > interesting if there are two or more infinite streams as the sources as can > be seen from the first of the next two examples (even is always 0). So, there > is an optional flag, fairOrder, which visits the streams one index level at a > time, (sort of breadth first vs depth first). > {code:groovy} > assert Iterators.combineLazy( > even: Iterators.iterate(0, n -> n + 2), > odd: Iterators.iterate(1, n -> n + 2), false) > .take(10).collect().join('\n') > == ''' > [even:0, odd:1] > [even:0, odd:3] > [even:0, odd:5] > [even:0, odd:7] > [even:0, odd:9] > [even:0, odd:11] > [even:0, odd:13] > [even:0, odd:15] > [even:0, odd:17] > [even:0, odd:19] > '''.trim() > assert Iterators.combineLazy( > even: Iterators.iterate(0, n -> n + 2), > odd: Iterators.iterate(1, n -> n + 2), true) > .take(10).collect().join('\n') > == ''' > [even:0, odd:1] > [even:0, odd:3] > [even:2, odd:1] > [even:2, odd:3] > [even:0, odd:5] > [even:2, odd:5] > [even:4, odd:1] > [even:4, odd:3] > [even:4, odd:5] > [even:0, odd:7] > '''.trim() > {code} > There are some more things to think about to fully utilise some of the > functionality from Groovy-stream but these cross product generators seem like > a nice start. -- This message was sent by Atlassian Jira (v8.20.10#820010)