From 302458fe987fd22877ab2408255c0e2b2ca17e51 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 7 Sep 2019 15:50:14 +0200 Subject: [PATCH 1/2] Allow broadcasting All and Between --- src/DataAPI.jl | 14 ++++++++++++++ test/runtests.jl | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/src/DataAPI.jl b/src/DataAPI.jl index 7fbbd29..69e1ae8 100644 --- a/src/DataAPI.jl +++ b/src/DataAPI.jl @@ -144,6 +144,13 @@ Between(x::AbstractString, y::AbstractString) = Between(Symbol(x), Symbol(y)) Between(x::Union{Int, Symbol}, y::AbstractString) = Between(x, Symbol(y)) Between(x::AbstractString, y::Union{Int, Symbol}) = Between(Symbol(x), y) +struct BroadcastedBetween{T1 <: Union{Int, Symbol}, T2 <: Union{Int, Symbol}} + first::T1 + last::T2 +end + +Base.Broadcast.broadcastable(x::Between) = Ref(BroadcastedBetween(x.first, x.last)) + """ All(cols...) @@ -169,6 +176,13 @@ struct Cols{T<:Tuple} Cols(args...) = new{typeof(args)}(args) end +struct BroadcastedAll{T<:Tuple} + cols::T + BroadcastedAll(args...) = new{typeof(args)}(args) +end + +Base.Broadcast.broadcastable(x::All) = Ref(BroadcastedAll(x.cols...)) + """ unwrap(x) diff --git a/test/runtests.jl b/test/runtests.jl index b62734c..471e2e8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -63,6 +63,9 @@ end b = DataAPI.Between(x, y) @test b.first == (x isa Int ? x : Symbol(x)) @test b.last == (y isa Int ? y : Symbol(y)) + + @test (b .=> sum) === (DataAPI.BroadcastedBetween(x, y) => sum) + @test (b .=> [sum, float]) == (Ref(DataAPI.BroadcastedBetween(x, y)) .=> [sum, float]) end @test_throws MethodError DataAPI.Between(true, 1) @@ -83,6 +86,11 @@ end @test a.cols[1].cols == () end + @test (DataAPI.All() .=> sum) === (DataAPI.BroadcastedAll() => sum) + @test (DataAPI.All(:a) .=> sum) === (DataAPI.BroadcastedAll(:a) => sum) + @test (DataAPI.All((1,2,3), :b) .=> sum) === (DataAPI.BroadcastedAll((1,2,3), :b) => sum) + @test (DataAPI.All() .=> [sum, float]) == (Ref(DataAPI.BroadcastedAll()) .=> [sum, float]) + end @testset "unwrap" begin From f518a6aabe40388ee03d4c505ff6136b6e999095 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Thu, 2 Sep 2021 22:17:31 +0200 Subject: [PATCH 2/2] Use BroadcastedSelector --- src/DataAPI.jl | 36 +++++++++++++++++++++++++----------- test/runtests.jl | 20 +++++++++++++------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/DataAPI.jl b/src/DataAPI.jl index 69e1ae8..0924732 100644 --- a/src/DataAPI.jl +++ b/src/DataAPI.jl @@ -144,13 +144,6 @@ Between(x::AbstractString, y::AbstractString) = Between(Symbol(x), Symbol(y)) Between(x::Union{Int, Symbol}, y::AbstractString) = Between(x, Symbol(y)) Between(x::AbstractString, y::Union{Int, Symbol}) = Between(Symbol(x), y) -struct BroadcastedBetween{T1 <: Union{Int, Symbol}, T2 <: Union{Int, Symbol}} - first::T1 - last::T2 -end - -Base.Broadcast.broadcastable(x::Between) = Ref(BroadcastedBetween(x.first, x.last)) - """ All(cols...) @@ -176,12 +169,33 @@ struct Cols{T<:Tuple} Cols(args...) = new{typeof(args)}(args) end -struct BroadcastedAll{T<:Tuple} - cols::T - BroadcastedAll(args...) = new{typeof(args)}(args) +""" + BroadcastedSelector(selector) + +Wrapper type around a `Between`, `All` or `Cols` indicating that +an operation should be applied to each column included by the wrapped selector. + +# Examples +```jldoctest +julia> using DataAPI + +julia> DataAPI.Between(:a, :e) .=> sin +DataAPI.BroadcastedSelector{DataAPI.Between{Symbol, Symbol}}(DataAPI.Between{Symbol, Symbol}(:a, :e)) => sin + +julia> DataAPI.Cols(r"x") .=> [sum, prod] +2-element Vector{Pair{DataAPI.BroadcastedSelector{DataAPI.Cols{Tuple{Regex}}}, _A} where _A}: + DataAPI.BroadcastedSelector{DataAPI.Cols{Tuple{Regex}}}(DataAPI.Cols{Tuple{Regex}}((r"x",))) => sum + DataAPI.BroadcastedSelector{DataAPI.Cols{Tuple{Regex}}}(DataAPI.Cols{Tuple{Regex}}((r"x",))) => prod +``` +""" +struct BroadcastedSelector{T} + sel::T + BroadcastedSelector(sel) = new{typeof(sel)}(sel) end -Base.Broadcast.broadcastable(x::All) = Ref(BroadcastedAll(x.cols...)) +Base.Broadcast.broadcastable(x::Between) = Ref(BroadcastedSelector(x)) +Base.Broadcast.broadcastable(x::All) = Ref(BroadcastedSelector(x)) +Base.Broadcast.broadcastable(x::Cols) = Ref(BroadcastedSelector(x)) """ unwrap(x) diff --git a/test/runtests.jl b/test/runtests.jl index 471e2e8..a086310 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -64,8 +64,10 @@ end @test b.first == (x isa Int ? x : Symbol(x)) @test b.last == (y isa Int ? y : Symbol(y)) - @test (b .=> sum) === (DataAPI.BroadcastedBetween(x, y) => sum) - @test (b .=> [sum, float]) == (Ref(DataAPI.BroadcastedBetween(x, y)) .=> [sum, float]) + @test (b .=> sum) === + (DataAPI.BroadcastedSelector(DataAPI.Between(x, y)) => sum) + @test (b .=> [sum, float]) == + (Ref(DataAPI.BroadcastedSelector(DataAPI.Between(x, y))) .=> [sum, float]) end @test_throws MethodError DataAPI.Between(true, 1) @@ -84,12 +86,16 @@ end @test length(a.cols) == 1 @test a.cols[1] isa v @test a.cols[1].cols == () - end - @test (DataAPI.All() .=> sum) === (DataAPI.BroadcastedAll() => sum) - @test (DataAPI.All(:a) .=> sum) === (DataAPI.BroadcastedAll(:a) => sum) - @test (DataAPI.All((1,2,3), :b) .=> sum) === (DataAPI.BroadcastedAll((1,2,3), :b) => sum) - @test (DataAPI.All() .=> [sum, float]) == (Ref(DataAPI.BroadcastedAll()) .=> [sum, float]) + @test (v() .=> sum) === + (DataAPI.BroadcastedSelector(v()) => sum) + @test (v(:a) .=> sum) === + (DataAPI.BroadcastedSelector(v(:a)) => sum) + @test (v((1,2,3), :b) .=> sum) === + (DataAPI.BroadcastedSelector(v((1,2,3), :b)) => sum) + @test (v() .=> [sum, float]) == + (Ref(DataAPI.BroadcastedSelector(v())) .=> [sum, float]) + end end