Skip to content

Commit 8e67e4e

Browse files
author
Pietro Vertechi
authored
add missing vector methods (#206)
* add missing vector methods * fix pop! * add vector method tests * add tests for inplace vector methods * bump version number
1 parent 7b479c4 commit 8e67e4e

File tree

4 files changed

+118
-20
lines changed

4 files changed

+118
-20
lines changed

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "StructArrays"
22
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
3-
version = "0.6.3"
3+
version = "0.6.4"
44

55
[deps]
66
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

src/structarray.jl

+24-8
Original file line numberDiff line numberDiff line change
@@ -362,21 +362,37 @@ Base.@propagate_inbounds function Base.setindex!(s::StructArray{<:Any, <:Any, <:
362362
s
363363
end
364364

365-
function Base.push!(s::StructVector, vals)
366-
foreachfield(push!, s, vals)
367-
return s
365+
for f in (:push!, :pushfirst!)
366+
@eval function Base.$f(s::StructVector, vals)
367+
foreachfield($f, s, vals)
368+
return s
369+
end
368370
end
369371

370-
function Base.pop!(s::StructVector{T}) where T
371-
t = map(pop!, components(s))
372-
return createinstance(T, t...)
372+
for f in (:append!, :prepend!)
373+
@eval function Base.$f(s::StructVector, vals::StructVector)
374+
foreachfield($f, s, vals)
375+
return s
376+
end
373377
end
374378

375-
function Base.append!(s::StructVector, vals::StructVector)
376-
foreachfield(append!, s, vals)
379+
function Base.insert!(s::StructVector, i::Integer, vals)
380+
foreachfield((v, val) -> insert!(v, i, val), s, vals)
377381
return s
378382
end
379383

384+
for f in (:pop!, :popfirst!)
385+
@eval function Base.$f(s::StructVector{T}) where T
386+
t = map($f, components(s))
387+
return createinstance(T, t...)
388+
end
389+
end
390+
391+
function Base.deleteat!(s::StructVector{T}, idxs) where T
392+
t = map(Base.Fix2(deleteat!, idxs), components(s))
393+
return StructVector{T}(t)
394+
end
395+
380396
Base.copyto!(I::StructArray, J::StructArray) = (foreachfield(copyto!, I, J); I)
381397

382398
function Base.copyto!(I::StructArray, doffs::Integer, J::StructArray, soffs::Integer, n::Integer)

src/tables.jl

+13-11
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ function try_compatible_columns(rows::R, s::StructArray) where {R}
2121
return Tables.columntable(rows)
2222
end
2323

24-
function Base.append!(s::StructVector, rows)
25-
table = try_compatible_columns(rows, s)
26-
if table !== nothing
27-
# Input `rows` is a container of rows _and_ satisfies column
28-
# table interface. Thus, we can add the input column-by-column.
29-
foreachfield(append!, s, table)
30-
return s
31-
else
32-
# Otherwise, fallback to a generic implementation expecting
33-
# that `rows` is an iterator:
34-
return foldl(push!, rows; init = s)
24+
for (f, g) in zip((:append!, :prepend!), (:push!, :pushfirst!))
25+
@eval function Base.$f(s::StructVector, rows)
26+
table = try_compatible_columns(rows, s)
27+
if table !== nothing
28+
# Input `rows` is a container of rows _and_ satisfies column
29+
# table interface. Thus, we can add the input column-by-column.
30+
foreachfield($f, s, table)
31+
return s
32+
else
33+
# Otherwise, fallback to a generic implementation expecting
34+
# that `rows` is an iterator:
35+
return foldl($g, rows; init = s)
36+
end
3537
end
3638
end

test/runtests.jl

+80
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,86 @@ end
161161
@test c == d
162162
end
163163

164+
struct C
165+
a::Int
166+
b::Int
167+
c::String
168+
end
169+
170+
@testset "in-place vector methods" begin
171+
c = StructArray(a=[1], b=[2], c=["a"])
172+
push!(c, (a=10, b=20, c="A"))
173+
@test c == StructArray(a=[1,10], b=[2,20], c=["a","A"])
174+
@test pop!(c) == (a=10, b=20, c="A")
175+
@test c == StructArray(a=[1], b=[2], c=["a"])
176+
177+
c = StructArray(a=[1], b=[2], c=["a"])
178+
pushfirst!(c, (a=10, b=20, c="A"))
179+
@test c == StructArray(a=[10,1], b=[20,2], c=["A","a"])
180+
@test popfirst!(c) == (a=10, b=20, c="A")
181+
@test c == StructArray(a=[1], b=[2], c=["a"])
182+
183+
c = StructArray(a=[1,2,3], b=[2,3,4], c=["a","b","c"])
184+
d = insert!(c, 2, (a=10, b=20, c="A"))
185+
@test d == c == StructArray(a=[1,10,2,3], b=[2,20,3,4], c=["a","A","b","c"])
186+
d = deleteat!(c, 2)
187+
@test d == c == StructArray(a=[1,2,3], b=[2,3,4], c=["a","b","c"])
188+
189+
c = StructArray(a=[1], b=[2], c=["a"])
190+
d = [(a=10, b=20, c="A")]
191+
e = append!(c, d)
192+
193+
@test e == c == StructArray(a=[1,10], b=[2,20], c=["a","A"])
194+
195+
c = StructArray(a=[1], b=[2], c=["a"])
196+
d = [(a=10, b=20, c="A")]
197+
e = prepend!(c, d)
198+
199+
@test e == c == StructArray(a=[10,1], b=[20,2], c=["A","a"])
200+
201+
c = StructArray(a=[1,2,3], b=[1,4,6], c=["a","b","c"])
202+
d = filter!(c) do el
203+
return isodd(el.a) && iseven(el.b)
204+
end
205+
@test d == c == StructArray(a=[3], b=[6], c=["c"])
206+
207+
c = StructArray{C}(a=[1], b=[2], c=["a"])
208+
push!(c, C(10, 20, "A"))
209+
@test c == StructArray{C}(a=[1,10], b=[2,20], c=["a","A"])
210+
@test pop!(c) == C(10, 20, "A")
211+
@test c == StructArray{C}(a=[1], b=[2], c=["a"])
212+
213+
c = StructArray{C}(a=[1], b=[2], c=["a"])
214+
pushfirst!(c, C(10, 20, "A"))
215+
@test c == StructArray{C}(a=[10,1], b=[20,2], c=["A","a"])
216+
@test popfirst!(c) == C(10, 20, "A")
217+
@test c == StructArray{C}(a=[1], b=[2], c=["a"])
218+
219+
c = StructArray{C}(a=[1,2,3], b=[2,3,4], c=["a","b","c"])
220+
d = insert!(c, 2, C(10, 20, "A"))
221+
@test d == c == StructArray{C}(a=[1,10,2,3], b=[2,20,3,4], c=["a","A","b","c"])
222+
d = deleteat!(c, 2)
223+
@test d == c == StructArray{C}(a=[1,2,3], b=[2,3,4], c=["a","b","c"])
224+
225+
c = StructArray{C}(a=[1], b=[2], c=["a"])
226+
d = [C(10, 20, "A")]
227+
e = append!(c, d)
228+
229+
@test e == c == StructArray{C}(a=[1,10], b=[2,20], c=["a","A"])
230+
231+
c = StructArray{C}(a=[1], b=[2], c=["a"])
232+
d = [C(10, 20, "A")]
233+
e = prepend!(c, d)
234+
235+
@test e == c == StructArray{C}(a=[10,1], b=[20,2], c=["A","a"])
236+
237+
c = StructArray{C}(a=[1,2,3], b=[1,4,6], c=["a","b","c"])
238+
d = filter!(c) do el
239+
return isodd(el.a) && iseven(el.b)
240+
end
241+
@test d == c == StructArray{C}(a=[3], b=[6], c=["c"])
242+
end
243+
164244
@testset "iterators" begin
165245
c = [1, 2, 3, 1, 1]
166246
d = StructArrays.GroupPerm(c)

0 commit comments

Comments
 (0)