[ 
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)

Reply via email to