Multiply Structarray with scalars per field

s = StructArray{NamedTuple{(:a, :b, :c, :d), NTuple{4, Float32}}}((a=[0,1,1,1,2,2,2],b=[0,0,0,0,0,0,0],c=[0,20,10,10,20,20,10],d=[0,6,5,4,3,2,1]))

factors = (a = 0.9, c = 1.2, d=2.0, b=0.2)

How to multiply a with factors?

julia> s * factors
ERROR: MethodError: no method matching *(::StructVector{NamedTuple{(:a, :b, :c, :d), NTuple{4, Float32}}, NamedTuple{(:a, :b, :c, :d), NTuple{4, Vector{Int64}}}, Int64}, ::NamedTuple{(:a, :b, :c, :d), NTuple{4, Float64}})

julia> s .* factors
ERROR: ArgumentError: broadcasting over dictionaries and `NamedTuple`s is reserved

Iteration over keys and rows does also not work: s[2][keys(factors)[1]] gives access to values but does not allow modifying them … Is there a way for accessing and modifying a column of s via the keys of factors? And why this behaviour:

julia> s.a
7-element Vector{Int64}:
 0
 6
 5
 4
 3
 2
 1

julia> s.a = s.a * 2
ERROR: type StructArray has no field a

Thanks

Hello and welcome,
I have never used StructArrays, and I’m sure someone will chime in with a better answer, but it looks like you either have to tell Julia how to multiply these things, or there might be another way to accomplish what you want in the library.

Strange as it may seem, your StructArray really does have no field a:

julia> fieldnames(typeof(s))
(:components,)

You can see the logic that gives you the 7-element Vector{Int64} like this (assuming you have an editor environment variable set up):

julia> ENV["EDITOR"]
"vim"
julia> @edit s.a

This shows you that Julia is using this function to look up a:

Base.getproperty(s::StructArray, key::Symbol) = component(s, key)

I also don’t think that s.a can be assigned to … it looks like what you are getting back is a new object, and not the a component of your StructArray.