Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating one field in every element of a Matlab struct array

Tags:

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.

like image 370
Carl Avatar asked Feb 15 '12 23:02

Carl


People also ask

How do you set a field in Matlab?

S = setfield( S , field , value ) assigns a value to the specified field of the structure S . For example, S = setfield(S,'a',1) makes the assignment S.a = 1 . As an alternative to setfield , use dot notation: S. field = value .

Can you make an array of structs in Matlab?

You can create an array of structures from a scalar structure by using the MATLAB repmat function, which replicates and tiles an existing scalar structure: Create a scalar structure, as described in Define Scalar Structures for Code Generation.

What is struct with fields in Matlab?

Arrays with named fields that can contain data of varying types and sizes. A structure array is a data type that groups related data using data containers called fields. Each field can contain any type of data. Access data in a structure using dot notation of the form structName.


2 Answers

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){:}).

like image 103
mathematical.coffee Avatar answered Sep 28 '22 06:09

mathematical.coffee


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));   
like image 33
Stan Shepherd Avatar answered Sep 28 '22 06:09

Stan Shepherd