Skip to content

Commit 49478a5

Browse files
authored
Support changing storage type (#52)
1 parent 7d05ac2 commit 49478a5

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/utils.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,38 @@ iscompatible(::Type{S}, ::Type{<:AbstractArray{T}}) where {S, T} = S<:T
7878
function iscompatible(::Type{S}, ::Type{StructArray{T, N, C}}) where {S, T, N, C}
7979
all_types(iscompatible, staticschema(S), C)
8080
end
81+
82+
function replace_storage(f, v::AbstractArray{T, N})::AbstractArray{T, N} where {T, N}
83+
f(v)
84+
end
85+
86+
"""
87+
`replace_storage(f, s::StructArray)`
88+
89+
Change storage type for fieldarrays: each array `v` is replaced by `f(v)`. `f(v) is expected to have the same
90+
`eltype` and `size` as `v`.
91+
92+
## Examples
93+
94+
If PooledArrays is loaded, we can pool all columns of non `isbitstype`:
95+
96+
```jldoctest
97+
julia> using PooledArrays
98+
99+
julia> s = StructArray(a=1:3, b = fill("string", 3));
100+
101+
julia> s_pooled = StructArrays.replace_storage(s) do v
102+
isbitstype(eltype(v)) ? v : convert(PooledArray, v)
103+
end
104+
10-element StructArray{NamedTuple{(:a, :b),Tuple{Int64,String}},1,NamedTuple{(:a, :b),Tuple{UnitRange{Int64},PooledArray{String,UInt8,1,Array{UInt8,1}}}}}:
105+
(a = 1, b = "string")
106+
(a = 2, b = "string")
107+
(a = 3, b = "string")
108+
```
109+
"""
110+
function replace_storage(f, s::StructArray{T}) where T
111+
cols = fieldarrays(s)
112+
newcols = map(t -> replace_storage(f, t), cols)
113+
StructArray{T}(newcols)
114+
end
115+

test/runtests.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ end
1919
@test StructArrays.propertynames(StructArrays.fieldarrays(t)) == (:a, :b)
2020
end
2121

22+
@testset "replace_storage" begin
23+
v = StructArray(a=rand(10), b = fill("string", 10))
24+
v_pooled = StructArrays.replace_storage(v) do c
25+
isbitstype(eltype(c)) ? c : convert(PooledArrays.PooledArray, c)
26+
end
27+
@test eltype(v) == eltype(v_pooled)
28+
@test all(v.a .== v_pooled.a)
29+
@test all(v.b .== v_pooled.b)
30+
@test !isa(v_pooled.a, PooledArrays.PooledArray)
31+
@test isa(v_pooled.b, PooledArrays.PooledArray)
32+
end
33+
2234
@testset "permute" begin
2335
a = WeakRefStrings.StringVector(["a", "b", "c"])
2436
b = PooledArrays.PooledArray([1, 2, 3])

0 commit comments

Comments
 (0)