更新 Matlab 结构体数组的每个元素中的一个字段

发布于 2025-01-06 09:09:33 字数 388 浏览 0 评论 0原文

假设我有一个结构体数组 arr,其中每个元素都有一堆字段,其中包括一个名为 val 的字段。我想将每个元素的 val 字段增加一些恒定量,如下所示:

for i = 1:length(arr)
    arr(i).val = arr(i).val + 3;
end

这显然有效,但我觉得应该有一种方法可以仅用一行代码来完成此操作(并且没有环形)。我想出的最好的办法是两行,并且需要一个临时变量:

newVals = num2cell([arr.val] + 3);
[arr.val] = deal(newVals{:});

有什么想法吗?谢谢。

Suppose I have a struct array arr, where each element has a bunch of fields, including one called val. I'd like to increment each element's val field by some constant amount, like so:

for i = 1:length(arr)
    arr(i).val = arr(i).val + 3;
end

This obviously works, but I feel there should be a way to do this in just one line of code (and no for loop). The best I've come up with is two lines and requires a temp variable:

newVals = num2cell([arr.val] + 3);
[arr.val] = deal(newVals{:});

Any ideas? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烂人 2025-01-13 09:09:33

请注意,此处不需要 deal

[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})

我知道如何执行此操作的唯一其他方法(无需 foo 循环)是使用 arrayfun 迭代每个结构在数组中:

% make a struct array
arr = [ struct('val',0,'id',1), struct('val',0,'id',2), struct('val',0,'id',3) ]

% some attempts
[arr.val]=arr.val; % fine
[arr.val]=arr.val+3; % NOT fine :(

% works !
arr2 = arrayfun(@(s) setfield(s,'val',s.val+3),arr)

最后一个命令循环遍历 arr 中的每个结构,并返回一个新结构,其中 s.val 已设置为 s.val=3.

我认为这实际上比之前的两行代码和 for 循环效率低,因为它返回 arr 的副本,而不是就地操作。

(遗憾的是,Matlab 不支持分层索引,例如 [arr.val]=num2cell([arr.val]+3){:})。

Just a note, the deal isn't necessary there:

[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})

The only other way I know how to do this (without the foor loop) is using arrayfun to iterate over each struct in the array:

% make a struct array
arr = [ struct('val',0,'id',1), struct('val',0,'id',2), struct('val',0,'id',3) ]

% some attempts
[arr.val]=arr.val; % fine
[arr.val]=arr.val+3; % NOT fine :(

% works !
arr2 = arrayfun(@(s) setfield(s,'val',s.val+3),arr)

That last command loops over each struct in arr and returns a new one where s.val has been set to s.val=3.

I think this is actually less efficient than your previous two-liner and the for loop though, because it returns a copy of arr as opposed to operating in-place.

(It's a shame Matlab doesn't support layered indexing like [arr.val]=num2cell([arr.val]+3){:}).

浅紫色的梦幻 2025-01-13 09:09:33

我喜欢 Carl 和 Mathematical.coffee 的原创想法。
我有多个相似的行要表达,所以为了简洁我的主线代码,
我继续制作通用子函数,

function varargout = clist(in)
varargout = {in{:}};
end

然后我可以以相当可读的方式表达每一行

[arr.var]  = clist(num2cell([arr.var]+3));  
[arr.var2] = clist(num2cell([arr2.var]/5+33));  

I like Carl's and mathematical.coffee's original ideas.
I have multiple similar lines to express, so for concision of my mainline code,
I went ahead and made the generic subfunction

function varargout = clist(in)
varargout = {in{:}};
end

then I could express each such line in a fairly readable way

[arr.var]  = clist(num2cell([arr.var]+3));  
[arr.var2] = clist(num2cell([arr2.var]/5+33));  
梦归所梦 2025-01-13 09:09:33

该结构体中的所有字段都是标量还是大小相同?如果是这样,惯用的 Matlab 方法是将结构重新排列为每个字段中包含数组的标量结构,而不是字段中包含标量值的结构数组。然后您可以对字段进行矢量化操作,例如 arr.val = arr.val + 3;。看看是否可以重新排列数据。这样做在时间和记忆上都更加有效;这可能就是为什么 Matlab 不提供方便的语法来操作结构体数组的字段。

Are all the fields in that struct scalar, or the same size? If so, the idiomatic Matlab way to do this is to rearrange your struct to be a scalar struct with arrays in each of its fields, instead of an array of structs with scalar values in the fields. Then you can do vectorized operations on the fields, like arr.val = arr.val + 3;. See if you can rearrange your data. Doing it this way is much more efficient in both time and memory; that's probably why Matlab doesn't provide convenient syntax for operating over fields of arrays of structs.

大海や 2025-01-13 09:09:33

如果您尝试设置的结构体数组是一组图形对象(线句柄、图形句柄、轴句柄等),那么您需要使用函数 set

x = (1:10)';
Y = rand(10,5);
l = plot(x,Y,'-k'); % returns an array of line handles in l
set(l,'Color','r'); % sets the property 'Color' for all the five lines in l

if the struct array you are trying to set is a set of graphics objects (line handles, figure handles, axes handles, etc), then you need to use the function set:

x = (1:10)';
Y = rand(10,5);
l = plot(x,Y,'-k'); % returns an array of line handles in l
set(l,'Color','r'); % sets the property 'Color' for all the five lines in l
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文