Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guards on comprehensions #17097

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions base/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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