From 04e56db6a93a8ad21c7d5e3d58c681acb73b5722 Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Fri, 24 Jun 2016 21:13:24 -0400 Subject: [PATCH] Tests and documentation for guards on comprehensions. Fixes #550. Your move Jeff. [ci skip] --- base/generator.jl | 5 +++-- test/misc.jl | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/base/generator.jl b/base/generator.jl index 48e00c749b84e..e356aab33997a 100644 --- a/base/generator.jl +++ b/base/generator.jl @@ -5,8 +5,9 @@ Given a function `f` and an iterator `iter`, construct an iterator that yields the values of `f` applied to the elements of `iter`. -The syntax `f(x) for x in iter` is syntax for constructing an instance of this -type. +The syntax `f(x) [if cond(x)::Bool] for x in iter` is syntax for constructing an instance of this +type. The `[if cond(x)::Bool]` expression is optional and acts as a "guard", effectively +filtering out values where the condition is false. """ immutable Generator{I,F} f::F diff --git a/test/misc.jl b/test/misc.jl index e3ae6b72e8ce6..731a8c98dc0a4 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -387,3 +387,34 @@ end optstring = sprint(show, Base.JLOptions()) @test startswith(optstring, "JLOptions(") @test endswith(optstring, ")") + +# generators and guards + +let gen = (x for x in 1:10) + @test typeof(gen) <: Generator + @test gen.iter == 1:10 + @test gen.f(first(1:10)) == next(gen, start(gen))[1] + for (a,b) in zip(1:10,gen) + @test a == b + end +end + +let gen = (x * y for x in 1:10, y in 1:10) + @test gen == collect(1:10) .* collect(1:10)' + @test first(gen) == 1 + @test collect(gen)[1:10] == collect(1:10) +end + +let gen = Base.Generator(+, 1:10, 1:10, 1:10) + @test first(gen) == 3 + @test collect(gen) == collect(3:3:30) +end + +let gen = (x if x % 2 == 0 for x in 1:10), gen2 = Filter(x->x % 2 == 0, x for x in 1:10) + @test collect(gen) == collect(gen2) + @test collect(gen) == collect(2:2:10) +end + +let gen = ((x,y) if x % 2 == 0 && y % 2 == 0 for x in 1:10, y in 1:10), gen2 = Filter(x->x[1] % 2 == 0 && x[2] % 2 == 0, (x,y) for x in 1:10, y in 1:10) + @test collect(gen) == collect(gen2) +end