Dims
Dims

Reputation: 51019

How to duplicate structure field (of non-scalar structure) in Matlab?

Suppose I have non-scalar structure

res = struct(); res(1).name = 'hello'; res(2).name = 'world';

Now I want to copy entire content of name field to another field, say tag.

Neither of the following worked:

>> res.tag = res.name;
Scalar structure required for this assignment.

>> [res.tag] = [res.name];
Insufficient number of outputs from right hand side of equal sign to satisfy assignment.

>> {res.tag} = {res.name};
 {res.tag} = {res.name};
           ↑
Error: The expression to the left of the equals sign is not a valid target for an assignment.

Any other ideas?

Upvotes: 3

Views: 315

Answers (1)

Luis Mendo
Luis Mendo

Reputation: 112659

Use

[res(:).tag] = res(:).name;

or more simply, as you have discovered yourself:

[res.tag] = res.name;

The syntax with square brackets on the left-hand side is similar to that used for capturing several outputs returned by a function: [out1, out2] = fun(...); see MATLAB special characters.

Actually, the syntax res.tag produces a comma-separated list; and [...] is standard for assigning values to each element in one such list; see Assigning output from a comma-separated list.

The right-hand side of the assignment should be another comma-separated list. If it is a single element, or you want to specify a list manually, you need deal:

values = {10, 20};
[res.test] = values{:}; % works. {:} produces a comma-separated list
[res.test] = 10,20; % doesn't work. Use `deal`
[res.test] = deal(10,20); % works
[res.test] = 10; % doesn't work, unless `res` is scalar. Use `deal`
[res.test] = deal(10); % also works. 10 is repeated as needed

The reason why your attempt [res.tag] = [res.name]; doesn't work is that [res.name] on the right-hand side concatenates the results of the comma-separated list res.name into one array, and so it's the same case as [res.test] = 10; above.

Upvotes: 6

Related Questions