Narrow StructArray column types

I want to narrow these column types. I can do it one at a time manually but maybe there’s a better way. identity.(_) didn’t work.

julia> StructArray(a=Vector{Any}(rand(5)), b=Vector{Any}(rand(5)) )
5-element StructArray(::Vector{Any}, ::Vector{Any}) with eltype @NamedTuple{a, b}:
 @NamedTuple{a, b}((0.9282308678719537, 0.9848647055555134))
 @NamedTuple{a, b}((0.2580742576332571, 0.45883280224997147))
 @NamedTuple{a, b}((0.8899944547670227, 0.5606060252132816))
 @NamedTuple{a, b}((0.7046512156106842, 0.18001066881982664))
 @NamedTuple{a, b}((0.6687878815348817, 0.7925852221245484))

julia> StructArray(a=Vector{Any}(rand(5)), b=Vector{Any}(rand(5))) .|> identity
5-element StructArray(::Vector{Any}, ::Vector{Any}) with eltype @NamedTuple{a, b}:
 @NamedTuple{a, b}((0.0007615587764459031, 0.5426479399707382))
 @NamedTuple{a, b}((0.5182118109893461, 0.5552017482453195))
 @NamedTuple{a, b}((0.2730274753802372, 0.08245847093565661))
 @NamedTuple{a, b}((0.668993997937832, 0.10044871486211415))
 @NamedTuple{a, b}((0.6492358217756695, 0.4698322502870076))

FWIW, the example below constructs a new StructArray:

using StructArrays: components

sa = StructArray(a=Vector{Any}(rand(5)), b=Vector{Any}(rand(5)))

sb = StructArray(NamedTuple{fieldnames(eltype(sa))}(identity.(c) for c in values(components(sa))))
1 Like

I tend to use Accessors optics for that:

julia> using StructArrays, AccessorsExtra

julia> A = StructArray(a=Vector{Any}(rand(5)), b=Vector{Any}(rand(5)) )
5-element StructArray(::Vector{Any}, ::Vector{Any}) with eltype @NamedTuple{a, b}:
 @NamedTuple{a, b}((0.6630158704139273, 0.2264759648412541))
 @NamedTuple{a, b}((0.5410353524881278, 0.8091409548463714))
 @NamedTuple{a, b}((0.11891843722732054, 0.7064689641168419))
 @NamedTuple{a, b}((0.43124228839812506, 0.8170026667989915))
 @NamedTuple{a, b}((0.29525834661985517, 0.3913670009707778))

julia> B = @modify(identity, A[∗ₚ][∗])  # or A |> Properties() |> Elements() if you like more verbose
5-element StructArray(::Vector{Float64}, ::Vector{Float64}) with eltype @NamedTuple{a::Float64, b::Float64}:
 (a = 0.6630158704139273, b = 0.2264759648412541)
 (a = 0.5410353524881278, b = 0.8091409548463714)
 (a = 0.11891843722732054, b = 0.7064689641168419)
 (a = 0.43124228839812506, b = 0.8170026667989915)
 (a = 0.29525834661985517, b = 0.3913670009707778)
1 Like