Copy the values of multiple fields in a structure to another structure at once
64 views (last 30 days)
Show older comments
Amirhossein Moosavi
on 6 Jun 2019
Commented: clod1977
on 18 Aug 2023
Hello,
I want to copy the values of multiple fields in a structure to another structure at once (without loop). For example, suppose the following empty structure.
A.SM = []; p = repmat(A, 3, 1); % 3 is not fixed
Now, I want to copy the contents of another structure which is as follows:
X(1).SM(:)
ans =
4 0 5 0
1 0 1 0
ans =
5 3 0 4
1 1 0 2
ans =
5 4 0 3
2 1 0 1
"p.SM = X(1).SM" does not work.
Many thanks for your help!
4 Comments
Jan
on 6 Jun 2019
@Amirhossein Moosavi: I do not know a method to create a variable, which creates this:
X(1).SM(:)
ans =
4 0 5 0
1 0 1 0
ans =
5 3 0 4
1 1 0 2
ans =
5 4 0 3
2 1 0 1
Please post exactly, what your inputs are and what the wanted result for the "copy" procedure is. Currently I guess, that the optimal solution is:
p = X(1);
but again, I do not understand, what your X(1) is.
Accepted Answer
Walter Roberson
on 6 Jun 2019
Edited: Walter Roberson
on 6 Jun 2019
To do it without a loop, you would have a small number of choices:
- arrayfun() subsasgn . This can be used even when not all of p is being written to. It is rather obscure and not recommended. In nearly any case you would consider using subsasgn this way, any time efficiency you might gain would be outweighed by the cost of figuring out how to write the code, and debugging the code, and documenting it thoroughly. And arrayfun() is, except for some obscure cases that only Jan seems to ever use, slower than a loop
- In the case where all of p is being replaced, p = struct('SM', {X(1).SM}); This kind of approach can be useful and efficient in the situations in which it applies.
- struct2cell(p) and struct2cell(X(1).SM) and replace parts of the p converted cell with that, and then cell2struct() the result. This has a fair overhead.
- You might be able to rig something with setfield()
Typically the most efficient code for this kind of purpose is a loop, which also has the advantage of being really easy to read and debug.
Note: X(1).SM cannot possibly have the output you show. You would need to have one more layer of field name, or else X would have to be a non-scalar array, in which case you would be looking at X(:).SM
0 Comments
More Answers (2)
Bjorn Gustavsson
on 6 Jun 2019
Maybe there could be faster solutions - but regardless somewhere looping over the fields will have to occur, and unless this is an explicitly proven bottle-neck of the code (checked with profile), just get it to work...
This is my old function:
function S_out = merge_fields(S1,S2,field_names)
% MERGE_FIELDS - Merge all or some fields of S2 into S1.
%
% Calling:
% S_out = merge_fields(S1,S2,field_names)
% Input:
% S1 - struct that fields in S2 will be copied to
% S2 - struct whos fields will be copied to S1
% field_names - cell or string-array with names of fields to copy from S2
% to S1, optional input
% Output:
% S_out - struct with all or selected fields from S2 copied into S1
% Copyright Björn Gustavsson 2011-06-28, <bjorn.gustavsson@irf.se>
% This is free software, licensed under GNU GPL version 2 or later
S_out = S1;
fields2 = fieldnames(S2);
if nargin > 2
fields2 = intersect(field_names,fields2);
end
for curr_field = fields2(:)',
S_out = setfield(S_out,curr_field{:},getfield(S2,curr_field{:}));
end
HTH
1 Comment
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!