首页 > 解决方案 > 结构数组字段上的广播运算符(Julia)

问题描述

我有一个数组实例化结构(相同类型)。我想更改这些结构的某个字段的值。出于性能原因,我想避免使用 for 循环。这是一个玩具代码来说明我的工作:

mutable struct foo
    x
end

a,b = foo(5), foo(7)

arr = [a,b]

.-(getfield.(arr,:x),1)

我希望这会将 x 字段放入一个数组(指向实际 foo 的实际 x 字段的指针),然后将 -1 应用于所有这些。当我打电话a,b时,它们没有改变。我在调试后知道这是因为broadcast()getfieldBroadcast.materialize将字段具体化()到一个新数组中,即它被复制了。

有没有合适且高效的方法可以在没有循环的情况下做到这一点?

谢谢

标签: juliabroadcast

解决方案


正如Matt B.所指出的,循环应该很快。但是,如果您想避免循环(主要是为了方便),您可以编写:

foreach(v -> v.x -= 1, arr)

(这实际上是一种循环,但我不希望它比循环快)

或使用StructArrays.jl,根据我的经验,这非常好。你想要的可以像这样实现(使用你的arr):

using StructArrays
arr2 = StructArray(arr)
arr2.x .-= 1

并且 StructArrays.jl负责1从.xarr2

编辑如果与结构集合的循环StructArray相比,如果执行按列操作,有时可能会更快(在您的示例中,该字段具有类型,因此这应该不相关,但如果它具有例如类型并且结构具有许多领域你可以注意到差异)。forAnyInt


推荐阅读