I have a problem to solve, I think an array of structures would solve my problem, but, it's not possible in matlab as far as I've seen. Please help me with a work around!
I do not want a structure array. I need independent names for the structures.
So I need to be able to do this:
asdf = struct('A', 3, 'B', 0)
zxcv = struct('A', 7, 'B', 0)
arr = [asdf , zxcv]
FUNCTION 1:
for i = 1 : length(arr)
arr(i).A = arr(i).B
end
FUNCTION 2:
for i = 1 : length(arr)
arr(i).B = arr(i).A
end
FUNCTION 3 (structure is called by name):
asdf.A = 65
FUNCTION 4:
var = asdf.A + zxcv.A
Function 3 is important, I can't just have a structure array because there are so many independtly named structures, and I have to add and/or remove many at a time, and often. So keeping track of that exact index number for asdf in a massive structure array, is a moving target, and every index would need to be verified in the code for structure in every location.
I've seen other solutions, have not found one that fits all three functions shown above.
Solutions I looked at:
2) There was another thread, suggesting using a structure of strings of the names of the structures, but it doesn't allow you to write to the the structure, like in functions 1 and 2 above. I can't find the thread though. It was also answered by Stephen Cobeldick.
3) I even tried using eval with an array of strings named after the structures, but you can't write to eval, so that didn't work. https://www.mathworks.com/matlabcentral/answers/289850-not-sure-why-eval-name-of-a-variable-cannot-be-assigned-a-value
4) My only thought was to use this custom pointer library and use an array of pointers to the structures? I'm not super keen on using a custom library if matlab doesn't usually use pointers. https://www.mathworks.com/matlabcentral/answers/5798-array-pointers-in-matl
Any other solutions are welcome? Otherwise, maybe I need to switch to python or something.
Thanks in advance!

댓글 수: 4

Bruno Luong
Bruno Luong 2020년 9월 18일
편집: Bruno Luong 2020년 9월 18일
"I may have many structures, and many times I need to write/read individual variables."
"I do not want a structure array. I need independent names for the structures"
Allright then you HAVE to pay speed penalty. Period.
Why not chosen a right data structure? The price to pay for little accessing comfort can be quite hight.
AlexMatLab
AlexMatLab 2020년 9월 19일
Bruno, so what is the right data structure? I'm open to any sugestion.
Bruno Luong
Bruno Luong 2020년 9월 19일
편집: Bruno Luong 2020년 9월 19일
I largely recommend structure of array. Put A, B in (2 x D) arrays, column corresponding to variable names
arr = struct('name', ["asdf", "zxcv"], ...
'A', [3, 7], ...
'B', [0, 0]);
% function 1
arr.A = arr.B;
% function 2
arr.B = arr.A;
% function 3
arr.A(:,arr.name=="asdf") = 65
% function 4
var = sum(arr.A(:, ismember(arr.name, ["asdf", "zxcv"])))
Close to that struct of array above is table. But personally I don't care about table excepted when I want to display data nicely on screen or display data with uitable.
AlexMatLab
AlexMatLab 2020년 9월 20일
Thank you for your response, but I think for my case, Steven's answer better solves my problem.

댓글을 달려면 로그인하십시오.

 채택된 답변

Steven Lord
Steven Lord 2020년 9월 18일

1 개 추천

Consider a struct whose fields are themselves struct arrays.
arr.asdf = struct('A', 3, 'B', 2);
arr.zxcv = struct('A', 7, 'B', 5, 'C', 42);
You can access the fields in arr using dynamic field names
F = fieldnames(arr);
y = zeros(size(F));
Q = struct;
for k = 1:numel(F)
disp("Processing field " + F{k} + " of arr.")
y(k) = 2 * arr.(F{k}).A;
Q.(F{k}) = arr.(F{k}).B.^2;
end
disp('y is')
disp(y)
disp('Q is')
disp(Q)
arr.zxcv.B = arr.zxcv.A + 1;

추가 답변 (1개)

Matt J
Matt J 2020년 9월 18일
편집: Matt J 2020년 9월 18일

1 개 추천

I don't know if this is something you explored in (2), but if so, I don't see why it wouldn't cover what you are trying to do.
asdf = struct('A', 3, 'B', 0,'ID',"asdf")
zxcv = struct('A', 7, 'B', 0, 'ID',"zxcv")
arr = [asdf , zxcv];
arr([arr.ID]=="asdf").A=65;

댓글 수: 8

AlexMatLab
AlexMatLab 2020년 9월 18일
편집: AlexMatLab 2020년 9월 18일
Thank you for the response.
I thought of this as a possibility, iterating through the structure array for a matching string field. I didn't know you could write it so cleanly though. Isn't it very slow and inefficient just to set that one value? Iteration through array and string comparison each time?
I may have many structures, and many times I need to write/read individual variables.
Matt J
Matt J 2020년 9월 18일
편집: Matt J 2020년 9월 18일
For multiple assignments, you would not loop explicitly. You would do things like,
searchfor=["asdf","zxcv"];
[~,loc]=ismember(searchfor,[arr.ID]);
[arr(loc).A]=deal(65,83);
Stephen23
Stephen23 2020년 9월 18일
편집: Stephen23 2020년 9월 18일
"I thought of this as a possibility, iterating through the structure array for a matching string field."
Why on earth would you need to do any iterating?
"I didn't know you could write it so cleanly though. Isn't it very slow and inefficient just to set that one value?"
No. Using indexing to access elements of an array is quite efficient, regardless of the array class. I guess that comma-separated lists are reasonably efficient, but I have no idea what they could be compared against.
"Iteration through array and string comparison each time?"
The MATLAB way would be to compare entire arrays of names at once, not iterating and comparing one-at-a-time:
Matt J
Matt J 2020년 9월 18일
Isn't it very slow and inefficient just to set that one value? Iteration through array and string comparison each time?
Using ismember as I showed above would mitigate the inefficiency, but numeric indexing would be much more efficient. Your reason for why that's a bad option wasn't really clear to me.
AlexMatLab
AlexMatLab 2020년 9월 19일
Matt J. Ok this multiple assignments idea is good. But, now we're back to the issue that this statement brings up: "many independtly named structures, and I have to add and/or remove many at a time, and often" if I use ismemeber and deal, I have make sure the orders of arguments for searchfor and deal are the same. This becomes unwieldly quickly at high volume.
Alos this brings up another issue, what is if I need to access multiple variables? So to add to my question, I need to add this forth required function;
FUNCTION 4:
var = asdf.A + zxcv.A
Again though, this needs to be extrapolated to many independent vaiables. So by using the first method Matt showed, it would look like:
var = arr([arr.ID]=="asdf").A + arr([arr.ID]=="zxcv").A
So for each variable accessed, the computer must find [arr.ID] string array and internally, iterate the array comparing the strings for "asdf" to find the logitcal array which is used to index the structure array (this is what I meant by itterating Stephen Cobeldick). My point is asdf.A seems much faster than arr([arr.ID]=="asdf"), especially when the structure array is very large.
and I looked at the litature Stephen is providing, I don't think that contridicts my previous statement.
Store your individual struct arrays as fields in one larger struct like in the answer I posted.
mydata.asdf = struct('A', 1, 'B', 2);
mydata.zxcv = struct('A', 3, 'C', 4);
var1 = mydata.asdf.A + mydata.zxcv.A; % Don't use var as a variable name
If you need to add a new struct to mydata just assign to it like I did on the first two lines.
If you need to remove one of the struct arrays from mydata use rmfield.
AlexMatLab
AlexMatLab 2020년 9월 20일
Steven,
Ok, this makes a lot of sense. I think this is a really good solution.
Thank you Steven!
Good point about var variable name.
AlexMatLab
AlexMatLab 2020년 9월 20일
Thank you everyone for your responses.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Structures에 대해 자세히 알아보기

제품

릴리스

R2020b

질문:

2020년 9월 18일

댓글:

2020년 9월 20일

Community Treasure Hunt

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

Start Hunting!

Translated by