How to make a structure to be input of a function and then its updated version to be output of the function?

I want to make a structure to be input of a function and then do some analysis and add some fields to the structure and return the updated version of structure as the ouput of the function. I tried to use:
struct=function updatestruct(struct,...)
end
and it did not update the sruct and produced a new strucutre at the output loosing the previously stored data in the struct.

 Risposta accettata

function new_struct = update_struct(old_struct,add_field, add_val)
new_struct = old_struct;
new_struct.(add_field) = add_val;
end
Notes:
  • "function" comes before output
  • don't use struct as a variable name

8 Commenti

this is more in line with Matlab standard (see rmfield, for example):
function my_struct = update_struct_2(my_struct,add_field, add_val)
my_struct.(add_field) = add_val;
end
(mostly, it just makes me nervous thinking about what might go wrong in other languages)
Thanks Sindar for suggestions. For the first solution I need to change the name of structure which I hesitate to do so. For the second solution, as I said I will lose the previously stored data in the strucute and only the new value assigned in the function will be in the structure.
Are you wanting to append data to the end of an existing field, or are you wanting to create a new additional field in the structure leaving the other fields untouched ?
Neither of those issues occur in my tests. Call the function like this:
this_struct = struct('a',5);
this_struct = update_struct(this_struct,'b',7);
% or
this_struct = update_struct_2(this_struct,'b',7);
The final structure will be equivalent to
this_struct = struct('a',5,'b',7);
Note that the name within the function (output or input) has nothing to do with the way you call it.
If you want to mess with existing fields, you'll need to be more careful. Can you give us the specifics? Here are a few (untested) examples:
Multiply a field by some value
function my_struct = multiply_struct_field(my_struct,mult_field, mult_val)
my_struct.(mult_field) = my_struct.(mult_field).*mult_val;
end
Append a value to a (vector) field
function my_struct = append_struct_field(my_struct,append_field, append_val)
tmp = my_struct.(append_field);
tmp(end+1) = append_val;
my_struct.(append_field) = tmp;
% I don't have my Matlab available right now, so I can hold out hope that this one-line version would work:
% my_struct.(append_field)(end+1) = append_val;
end
Compare a value to a (scalar) field and keep the larger number
function my_struct = keep_max_struct_field(my_struct,max_field, new_val)
my_struct.(max_field) = max(my_struct.(max_field),new_val);
end
@Walter Roberson: I want to add new field but I would like to know the answer if I was planning to append some data to the end of existing field.
@Sindar @walter Robrson
By the way it is nested structure like:
struct.fieldA
and I am going to add
struct.fieldA.fieldAA
struct.fieldA.fieldAB
The nested struct aspect is key. Here's a version which can deal with either:
function new_struct = update_struct(new_struct,add_field, add_val,sub_struct)
% if no substruct is given, create field under the top struct
if nargin<4 || isempty(sub_struct)
new_struct.(add_field) = add_val;
% otherwise, create the field under the given substructure
else
new_struct.(sub_struct).(add_field) = add_val;
end
end
>> mystruct = struct('a',5,'b',struct('b1',2))
mystruct =
a: 5
b: [1×1 struct]
>> mystruct = update_struct(mystruct,'c',7)
mystruct =
a: 5
b: [1×1 struct]
c: 7
>> mystruct = update_struct(mystruct,'b2',7,'b')
mystruct =
a: 5
b: [1×1 struct]
c: 7
>> mystruct.b
ans =
b1: 2
b2: 7

Accedi per commentare.

Più risposte (1)

s = struct();
for K = 1 : 10
s = updatestruct(s);
end
for K = 1 : 10
s = updatestruct2(s);
end
disp(s)
function struct = updatestruct(struct)
fn = char('a' + randi([0 25], 1, 5));
struct.(fn) = randi([-99 99]);
fprintf('new field: %s\n', fn);
end
function struct = updatestruct2(struct)
names = fieldnames(struct);
fn = names{randi(length(names))};
struct.(fn)(end+1) = randi([-99 99]);
fprintf('updated field: %s\n', fn);
end
Example run:
>> demo
new field: bresh
new field: iznax
new field: ypcuj
new field: amzax
new field: yeqbz
new field: jtrij
new field: fibsk
new field: ocrsf
new field: mlrtr
new field: lqgqa
updated field: amzax
updated field: mlrtr
updated field: ocrsf
updated field: yeqbz
updated field: ocrsf
updated field: ocrsf
updated field: bresh
updated field: jtrij
updated field: fibsk
updated field: fibsk
bresh: [89 86]
iznax: -11
ypcuj: -47
amzax: [-98 -37]
yeqbz: [-64 -3]
jtrij: [26 4]
fibsk: [9 -95 -10]
ocrsf: [-85 -48 -11 -93]
mlrtr: [52 -52]
lqgqa: 57
You can see clearly that contrary to your claims, previous fields and values do not get removed when you update a struct.
"For the first solution I need to change the name of structure which I hesitate to do so."
Using "struct" as a variable name is bad practice. Just select one copy of the variable name and type in a new name and MATLAB will offer to rename it to something else if you press shift-return . It is so easy that there is no good reason not to do it. If the problem is that you have existing code that has already gone through code review that uses "struct" as a variable name, then the reviewers should never have permitted you to use that as a variable name.

2 Commenti

using strucut as the name was only for asking question. I did not use it in the reall code. Thanks
So use some other variable name only in the function header, and immediately assign it to the existing variable name
function variable_you_are_using_now = update_struct(old_struct, whatever_parameters)
variable_you_are_using_now = old_struct;
... your existing code that updates variable_you_are_using_now
end

Accedi per commentare.

Tag

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by