Arrays 在Matlab struct数组的每个元素中更新一个字段

Arrays 在Matlab struct数组的每个元素中更新一个字段,arrays,matlab,struct,field,assign,Arrays,Matlab,Struct,Field,Assign,假设我有一个结构数组arr,其中每个元素都有一组字段,包括一个名为val的字段。我想将每个元素的val字段增加一个常量,如下所示: for i = 1:length(arr) arr(i).val = arr(i).val + 3; end 这显然是可行的,但我觉得应该有一种方法可以在一行代码中实现这一点(并且没有for循环)。我想到的最好的方法是两行,需要一个临时变量: newVals = num2cell([arr.val] + 3); [arr.val] = deal(newVa

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

for i = 1:length(arr)
    arr(i).val = arr(i).val + 3;
end
这显然是可行的,但我觉得应该有一种方法可以在一行代码中实现这一点(并且没有for循环)。我想到的最好的方法是两行,需要一个临时变量:

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

有什么想法吗?谢谢。

请注意,
交易在那里是不必要的:

[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})
我知道的唯一其他方法(没有foor循环)是使用
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

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


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

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

如果您试图设置的结构数组是一组图形对象(线句柄、图形句柄、轴句柄等),那么您需要使用函数
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

我喜欢卡尔和数学。咖啡的原创思想。 我有多行类似的代码要表达,所以为了简洁我的主线代码, 我继续做了一般的子函数

function varargout = clist(in)
varargout = {in{:}};
end
然后,我可以用一种相当可读的方式来表达每一行

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

感谢您提供有关交易的提示。我不知道设置字段,所以这似乎是在一行中完成的,但正如您所说,这肯定比for循环解决方案更糟糕。至于像这样的索引,我前段时间已经研究过了;基本上,Mathworks声称支持任何类似的东西都会迫使解析器进行破坏兼容性的更改。这真是太遗憾了,因为几乎每次我写Matlab代码的时候,它都会让我感到厌烦。谢谢你的回答!在Matlab2013b中,[arr.val]=newVals{:}工作,但arr.val=newVals{:}。括号在这种情况下到底起什么作用?
arrayfun
只是MATLAB中
for
循环的包装器,所以从技术上讲,您仍然在使用循环,尽管是伪装的。结构数组中deal很有用的一种情况是,您希望为结构数组的每个元素的字段指定相同的值。例如,如果
v=9
,您可以编写
[arr.val]=deal(v)
将9分配给结构数组的每个元素的字段
val
arr
[arr.val]=newVals{:}工作,但
[arr.val]=newVals(:)不是-即如果newVals是向量而不是射线。有人能解释一下吗?!