Skip to content

Commit fcf126b

Browse files
authored
Merge pull request #30 from eliascarv/col-spec
ColSpec interface.
2 parents 193c0b1 + b34218e commit fcf126b

File tree

4 files changed

+124
-1
lines changed

4 files changed

+124
-1
lines changed

src/transforms.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ end
211211
# IMPLEMENTATIONS
212212
# ----------------
213213

214+
include("transforms/colspec.jl")
214215
include("transforms/select.jl")
215216
include("transforms/filter.jl")
216217
include("transforms/rename.jl")

src/transforms/colspec.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ------------------------------------------------------------------
2+
# Licensed under the MIT License. See LICENSE in the project root.
3+
# ------------------------------------------------------------------
4+
5+
# types used to select a column
6+
const ColSelector = Union{Symbol,Integer,AbstractString}
7+
8+
# filter table columns using colspec
9+
function _filter(colspec::Vector{Symbol}, cols)
10+
# validate columns
11+
@assert !isempty(colspec) "Invalid column selection."
12+
@assert colspec cols "Invalid column selection."
13+
return colspec
14+
end
15+
16+
_filter(colspec::Vector{<:AbstractString}, cols) =
17+
_filter(Symbol.(colspec), cols)
18+
19+
_filter(colspec::Vector{<:Integer}, cols::Vector) =
20+
_filter(cols[colspec], cols)
21+
22+
_filter(colspec::Vector{<:Integer}, cols::Tuple) =
23+
_filter(colspec, collect(cols))
24+
25+
_filter(colspec::NTuple{N,<:ColSelector}, cols) where {N} =
26+
_filter(collect(colspec), cols)
27+
28+
function _filter(colspec::Regex, cols::Vector)
29+
fcols = filter(col -> occursin(colspec, String(col)), cols)
30+
_filter(fcols, cols)
31+
end
32+
33+
_filter(colspec::Regex, cols::Tuple) =
34+
_filter(colspec, collect(cols))
35+
36+
_filter(::Colon, cols::Vector) = cols
37+
_filter(::Colon, cols::Tuple) = collect(cols)

src/transforms/filter.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ end
3939
# DropMissing
4040

4141
const VecOrTuple{T} = Union{Vector{T}, NTuple{N, T}} where {T, N}
42-
const ColSelector = Union{Symbol, Integer, AbstractString}
4342

4443
"""
4544
DropMissing()

test/transforms.jl

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,92 @@
11
@testset "Transforms" begin
22
# using MersenneTwister for compatibility between Julia versions
33
rng = MersenneTwister(42)
4+
@testset "ColSpec" begin
5+
veccols = [:a, :b, :c, :d, :e, :f]
6+
tupcols = (:a, :b, :c, :d, :e, :f)
7+
8+
# vector of symbols
9+
colspec = [:a, :c, :e]
10+
cols = TableTransforms._filter(colspec, veccols)
11+
@test cols == [:a, :c, :e]
12+
cols = TableTransforms._filter(colspec, tupcols)
13+
@test cols == [:a, :c, :e]
14+
15+
# tuple of symbols
16+
colspec = (:a, :c, :e)
17+
cols = TableTransforms._filter(colspec, veccols)
18+
@test cols == [:a, :c, :e]
19+
cols = TableTransforms._filter(colspec, tupcols)
20+
@test cols == [:a, :c, :e]
21+
22+
# vector of strings
23+
colspec = ["a", "c", "e"]
24+
cols = TableTransforms._filter(colspec, veccols)
25+
@test cols == [:a, :c, :e]
26+
cols = TableTransforms._filter(colspec, tupcols)
27+
@test cols == [:a, :c, :e]
28+
29+
# tuple of strings
30+
colspec = ("a", "c", "e")
31+
cols = TableTransforms._filter(colspec, veccols)
32+
@test cols == [:a, :c, :e]
33+
cols = TableTransforms._filter(colspec, tupcols)
34+
@test cols == [:a, :c, :e]
35+
36+
# vector of integers
37+
colspec = [1, 3, 5]
38+
cols = TableTransforms._filter(colspec, veccols)
39+
@test cols == [:a, :c, :e]
40+
cols = TableTransforms._filter(colspec, tupcols)
41+
@test cols == [:a, :c, :e]
42+
43+
# tuple of integers
44+
colspec = (1, 3, 5)
45+
cols = TableTransforms._filter(colspec, veccols)
46+
@test cols == [:a, :c, :e]
47+
cols = TableTransforms._filter(colspec, tupcols)
48+
@test cols == [:a, :c, :e]
49+
50+
# regex
51+
colspec = r"[ace]"
52+
cols = TableTransforms._filter(colspec, veccols)
53+
@test cols == [:a, :c, :e]
54+
cols = TableTransforms._filter(colspec, tupcols)
55+
@test cols == [:a, :c, :e]
56+
57+
# colon
58+
cols = TableTransforms._filter(:, veccols)
59+
@test cols == [:a, :b, :c, :d, :e, :f]
60+
cols = TableTransforms._filter(:, tupcols)
61+
@test cols == [:a, :b, :c, :d, :e, :f]
62+
63+
# throws
64+
@test_throws AssertionError TableTransforms._filter(r"x", veccols)
65+
@test_throws AssertionError TableTransforms._filter(r"x", tupcols)
66+
@test_throws AssertionError TableTransforms._filter(String[], veccols)
67+
@test_throws AssertionError TableTransforms._filter(String[], tupcols)
68+
@test_throws AssertionError TableTransforms._filter(Symbol[], veccols)
69+
@test_throws AssertionError TableTransforms._filter(Symbol[], tupcols)
70+
71+
# type stability
72+
@inferred TableTransforms._filter([:a, :b], veccols)
73+
@inferred TableTransforms._filter([:a, :b], tupcols)
74+
@inferred TableTransforms._filter((:a, :b), veccols)
75+
@inferred TableTransforms._filter((:a, :b), tupcols)
76+
@inferred TableTransforms._filter(["a", "b"], veccols)
77+
@inferred TableTransforms._filter(["a", "b"], tupcols)
78+
@inferred TableTransforms._filter(("a", "b"), veccols)
79+
@inferred TableTransforms._filter(("a", "b"), tupcols)
80+
@inferred TableTransforms._filter([1, 2], veccols)
81+
@inferred TableTransforms._filter([1, 2], tupcols)
82+
@inferred TableTransforms._filter((1, 2), veccols)
83+
@inferred TableTransforms._filter((1, 2), tupcols)
84+
@inferred TableTransforms._filter(r"[ab]", veccols)
85+
@inferred TableTransforms._filter(r"[ab]", tupcols)
86+
@inferred TableTransforms._filter(:, veccols)
87+
@inferred TableTransforms._filter(:, tupcols)
88+
end
89+
490
@testset "Select" begin
591
a = rand(4000)
692
b = rand(4000)

0 commit comments

Comments
 (0)