Calculate values of struct of struct
조회 수: 6 (최근 30일)
이전 댓글 표시
I have a struct with several fieldnames, each of them is again a struct and has a fieldname "P". This "P" is an array.
I want to calculate the sum of all "P "s like:
s.s1.P = (1:20).'; % For simplicity I have assigned dummy values to the "P "s.
s.s2.P = (1:20).';
s.s3.P = (1:20).';
% ...
result = s.s1.P + s.s2.P + s.s3.P % + ...
I have already a solution with a for loop:
field = fieldnames(s);
result = zeros(size(s.(field{1}).P));
for i = 1:length(field)
result = result +s.(field{i}).P;
end
I also tried to use "structfun" but were not able to get this result.
Is it possible to calculate this problem with "structfun" or another function or is the for loop the final solution for this problem?
댓글 수: 1
Stephen23
2023년 9월 4일
Rather than forcing pseudo-indices into fieldnames you should simply use a structure array, as dpb showed.
채택된 답변
Bruno Luong
2023년 9월 4일
편집: Bruno Luong
2023년 9월 4일
Single line (work for fields with struct NOT objects of class, struct is NOT some sort of class)
s.s1.P = (1:20).'; % For simplicity I have assigned dummy values to the "P "s.
s.s2.P = (1:20).';
s.s3.P = (1:20).';
sum([cat(1,struct('sx',struct2cell(s)).sx).P],2)
댓글 수: 0
추가 답변 (2개)
dpb
2023년 9월 4일
편집: dpb
2023년 9월 4일
The problem of using sequentially-named fields in the struct instead of an array of struct; there's no good way to process the resulting variables or struct fields programmatically when do so.
structfun applies the function to each field of a scalar struct so it isn't the tool for the purpose here, anyway, you're trying to process across fields, not within each. And, arrayfun is for an array but you didn't use an array to hold the similar data, you chose to use multiple fields instead. A 2D array would have been an alternate choice that could have handled easily...
s.P = (1:20).';
s.P = [s.P (1:20).'];
s.P = [s.P (1:20).'];
result = sum(s.P,2)
Or, alternatively, as a struct array
s.P = (1:20).';
s(2).P = (1:20).';
s(3).P = (1:20).';
result = sum([s.P],2)
댓글 수: 7
Bruno Luong
2023년 9월 4일
편집: Bruno Luong
2023년 9월 4일
No
D=delaunayTriangulation(rand(10,2))
structfun(@(D)D.Points, D)
Sorry my first remark on structfun on class is not applicable int the present context, since s is still a struct with 3 fields. structun can be applied on s.
Bruno Luong
2023년 9월 4일
편집: Bruno Luong
2023년 9월 4일
Honestly I prefer the for-loop
s.s1.P = (1:20).'; % For simplicity I have assigned dummy values to the "P "s.
s.s2.P = (1:20).';
s.s3.P = (1:20).';
c = struct2cell(structfun(@(sf) sf.P, s, 'UniformOutput', false));
sum(cat(2,c{:}),2)
댓글 수: 2
dpb
2023년 9월 4일
Given the already bad idea of having created the sequentially-named fields, agree, the for loop is the way; as your example shows, to do anything else gets far too convoluted and undoubtedly would be slower besides.
At least with struct fields, one can programmatically access them w/o the eval abomination.
참고 항목
카테고리
Help Center 및 File Exchange에서 Structures에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!