diff --git a/base/experimental.jl b/base/experimental.jl index 9edd197c198e9c..7861c628bbe275 100644 --- a/base/experimental.jl +++ b/base/experimental.jl @@ -359,4 +359,47 @@ adding them to the global method table. """ :@MethodTable +""" + astuple(x::Union{X, Nothing}) + +Converts values so that `nothing` becomes `()` and any other values are wrapped into a singleton tuple. + +# Example + +``` +julia> data = match.(r"(x.?)", ["x", "aoeu", "xoxo", ">>=", ";qjkx"]) +5-element Vector{Union{Nothing, RegexMatch}}: + RegexMatch("x", 1="x") + nothing + RegexMatch("xo", 1="xo") + nothing + RegexMatch("x", 1="x") + +julia> filter(!isnothing, data) +3-element Vector{Union{Nothing, RegexMatch}}: + RegexMatch("x", 1="x") + RegexMatch("xo", 1="xo") + RegexMatch("x", 1="x") + +julia> collect(Iterators.flatten(astuple.(data))) +3-element Vector{RegexMatch}: + RegexMatch("x", 1="x") + RegexMatch("xo", 1="xo") + RegexMatch("x", 1="x") + +julia> [optx for optx in data if !isnothing(optx) && optx[1] != "x"] +1-element Vector{RegexMatch}: + RegexMatch("xo", 1="xo") + +julia> Iterators.flatmap(astuple.(data)) do optx + Iterators.flatmap(optx) do x + x[1] == "x" ? () : (x,) + end + end |> collect +1-element Vector{RegexMatch}: + RegexMatch("xo", 1="xo") +``` +""" +astuple(x::Union{X, Nothing}) where {X} = isnothing(x) ? () : (x,) + end diff --git a/base/iterators.jl b/base/iterators.jl index ac53b4d36886e9..90b7d84fa47b7a 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -1209,9 +1209,6 @@ julia> flatmap(1:3) do j # flatmap = flatten ∘ map flatmap(f, c...) = flatten(map(f, c...)) -# Allows filtering through `flatten` (or `flatmap`) by removing `nothing` values -iterate(_::Nothing) = nothing - """ partition(collection, n) diff --git a/base/some.jl b/base/some.jl index c3be079f2dded6..8be58739a4df41 100644 --- a/base/some.jl +++ b/base/some.jl @@ -143,8 +143,3 @@ macro something(args...) something = GlobalRef(Base, :something) return :($something($expr)) end - -# Allows filtering through `flatten` (or `flatmap`) by retaining `Some` values -iterate(x::Some{T}) where T = (something(x), nothing) -iterate(x::Some{T}, state::Nothing) where T = nothing -length(x::Some{T}) where T = 1 diff --git a/test/iterators.jl b/test/iterators.jl index ff705d32fed2e5..acc906d1543c65 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -469,8 +469,7 @@ end @test length(flatten(1:6)) == 6 @test collect(flatten(Any[])) == Any[] @test collect(flatten(())) == Union{}[] -@test collect(flatten([Some(1)])) == [1] -@test collect(flatten([nothing])) == Any[] +@test collect(flatten(astuple.([1,nothing]))) == [1] @test_throws ArgumentError length(flatten(NTuple[(1,), ()])) # #16680 @test_throws ArgumentError length(flatten([[1], [1]])) @@ -480,11 +479,9 @@ end # flatmap # ------- -@test flatmap(1:3) do j - flatmap(1:3) do k - j>k ? Some((j,k)) : nothing - end - end |> collect == [(j,k) for j in 1:3 for k in 1:3 if j>k] +@test flatmap(1:3) do j flatmap(1:3) do k + j!=k ? ((j,k),) : () +end end |> collect == [(j,k) for j in 1:3 for k in 1:3 if j!=k] # partition(c, n) let v = collect(partition([1,2,3,4,5], 1))